반응형

 

@PreAuthorize()는 메서드를 실행하기 전에 하는 권한 검사

@PostAuthorize()는 메서드를 실행하고 클라이언트에게 응답을 하기 직전에 하는 권한 검사

 

<예시>

@PreAuthorize("isAuthenticated()")

 

인자로 올 수 있는 값...

  • hasRole([role]) : 현재 사용자의 권한이 파라미터의 권한과 동일한 경우 true
@PreAuthorize("hasRole('ADMIN') or hasRole('MANAGER')")

 

  • hasAnyRole([role1,role2]) : 현재 사용자의 권한이 파라미터의 권한 중 일치하는 것이 있는 경우 true
@PreAuthorize("hasAnyRole('ADMIN', 'MANAGER')")

 

  • principal : 사용자를 증명하는 주요객체(User)를 직접 접근할 수 있다.
  • authentication : SecurityContext에 있는 authentication 객체에 접근 할 수 있다.
@PreAuthorize("#userId == authentication.principal.id")
or
@PreAuthorize("#username == authentication.name")

 

  • permitAll() : 모든 접근 허용
  • denyAll() : 모든 접근 비허용
  • isAnonymous() : 현재 사용자가 익명(비로그인)인 상태인 경우 true
  • isRememberMe() : 현재 사용자가 RememberMe 사용자라면 true
  • isAuthenticated() : 현재 사용자가 익명이 아니라면 (로그인 상태라면) true
  • isFullyAuthenticated() : 현재 사용자가 익명이거나 RememberMe 사용자가 아니라면 true
@PreAuthorize("isAuthenticated()")
@PreAuthorize("isAnonymous()")

 

 

반응형
반응형

평생 공짜로 쓸 수 있다고 해서 Oracle Freetier에 장비 하나를 구성해두었습니다. 

한참 잊고 지내고 있었는데, 그때 돌려놓았던 node 서버가 여전히 잘 돌아가고 있더군요.

 

이번엔 Oracle Freetier서버에 ExpressJS로 백엔드 서비스를 구성하고,

Netlify에 Jquery로 통신이 가능한 웹프로그램을 구성해 보았습니다.

 

1. Oracle Freetier

Cloud Free Tier | Oracle 대한민국

 

클라우드 서비스 무료 이용

Oracle Cloud Free Tier는 기업에게 무제한으로 사용할 수 있는 상시 무료 클라우드 서비스를 제공합니다.

www.oracle.com

 

[src/index.js]

간단하게 'Hello World'만 return하는 서버를 만들어 두었습니다. Github에서 해당 서버로 자동배포하는 것까지 구성은 못해서 FTP로 일일이 옮겨넣었습니다.

var express = require('express');
var app = express();
var user = require('./routes/user');

const cors = require('cors');
app.use(cors());

app.get('/', function (req, res) {	// 기본 root('/') 는 main.js에서 routing
    res.send('Hello World');
});

//app.use('/user', user);         	// 나머지 접근은 router(/routes/user)에서 routing


app.listen(3000, function () {   	// 3000 포트로 서버 실행
    console.log('Example App is listening on port 3000');
});

소스코드에 보시면, 다른 서버로부터의 요청이 허용되도록 app.use(cors())를 선언해줘야합니다.

위치는 라우팅보다 앞에 선언되어야 합니다.

 

2. Netlify

Scale & Ship Faster with a Composable Web Architecture | Netlify

 

Scale & Ship Faster with a Composable Web Architecture | Netlify

Realize the speed, agility and performance of a scalable, composable web architecture with Netlify. Explore the composable web platform now!

www.netlify.com

 

Netlify는 Github이나 Gitlab과 연동이 잘 되어 별도의 구성 없이도 CI/CD가 쉽게 가능합니다. 그래서 다른 Front Framework 사용하지 않고 html하고 jquery만으로 데이터를 받아오는 연습을 해봤습니다.

 

[index.html]

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./js/jquery.min.js"></script>
</head>
<body>
 <div id="headline">Hello!!</div>
 <button onclick="ajax_request()">Ajax Request</button>
<script>
  function ajax_request(){
      $.ajax({
        url:'/api/', //'http://1xx.6xx.2xx.2xx:3000/', <- netlify에서 https요청으로 보내면, netlify.toml의 proxy설정을 통해 해당 서버로 요청됨
        method:'GET',
        async:false,
        success: function(data){
          console.log(data);
          document.getElementById('headline').innerText =data;
        }
      })
  }
 
</script>  
</body>
</html>

 

[netlify.toml]

[[redirects]]
  from = "/api/*"
  to = "http://1xx.6xx.2xx.2xx:3000/:splat"
  status = 200
  force = true

 

oracle 서버에서 cors 허용을 해놓았는데도 원래의 주소로 request를 보내면 오류가 납니다. 이유는 oracle에서는 http로 서비스를 하고 있고, netlify에서는 https로 서비스를 하고 있어서 그렇습니다. oracle에도 https서비스를 위한 인증서를 구해서 넣으면 좋지만, 위와 같이 proxy 우회 방법으로 간단히 두 서버간 통신이 가능합니다.

 

netlify에서는 ajax요청할 때, '/api/' 로 요청을 보내고,

netlify proxy설정을 통해 원래 서버로 전달됩니다.

 

 

그럼 이만~!

반응형

'Programming > ExpressJS' 카테고리의 다른 글

Node강좌 - 미들웨어  (0) 2020.08.09
Node강좌 - express 설치 / router설정  (0) 2020.08.09
반응형

 

위와 같이 프로젝트가 구성되있다고 할 때, pom.xml에 mybatis와 database driver를 설치해줍니다.

 

1. pom.xml (Maven기준)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>abc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>javafx03_mybatis</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.0</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.6</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>12.4.2.jre11</version>
            <scope>runtime</scope>
        </dependency>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>org.example.abc.HelloApplication</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

 

2. module-info.java

스프링처럼 사용하려면 module-info.java 파일이 필요함. 아래의 추가부분을 설정해준다. (이 부분을 몰라서 한참 헤멤)

module org.example.abc {
    requires javafx.controls;
    requires javafx.fxml;
    requires java.sql;
    requires org.mybatis;  // <-- Add this

    opens org.example.abc to javafx.fxml;
    exports org.example.abc;
    exports org.example.abc.mapper;
    opens org.example.abc.mapper to javafx.fxml;
    exports org.example.abc.dto;
    opens org.example.abc.dto to javafx.fxml;
    opens mapper; // <-- 이거 추가해야 mapper 인식
}

 

3. MyBatisUtil.java

 

package org.example.abc;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }

    public static SqlSession getSession() {
        return sqlSessionFactory.openSession();
    }
}

 

4. mybatis-config.xml

특별한 건 없습니다. DB 접속정보를 적어주고, Mapper의 위치를 적어줍니다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://<databaseURL>:<port_number>;databaseName=<DB>;encrypt=true;trustServerCertificate=true;"/>
                <property name="username" value="<username>"/>
                <property name="password" value="<password>"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/<매퍼이름>.xml"/>
    </mappers>
</configuration>

 

Mapper.xml 상세와 DTO, UI상세 등은 Spring과 동일함.

반응형
반응형
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://<주소>:<포트>;databaseName=<DB이름>;encrypt=true;trustServerCertificate=true;"/>
                <property name="username" value="이름"/>
                <property name="password" value="비밀번호"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/dbMapper.xml"/>
        <mapper resource="mapper/itemMapper.xml"/>
    </mappers>
</configuration>

 

encrypt=true;trustServerCertificate=true;

이 구문을 넣어줘야한다.

반응형
반응형

프로젝트 구조

 

1. 프로젝트 생성시 Mavin으로 생성

- pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>swing02_mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc11 -->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc11</artifactId>
            <version>23.5.0.24.07</version>
        </dependency>

        <dependency>
            <groupId>com.oracle.ojdbc</groupId>
            <artifactId>orai18n</artifactId>
            <version>19.3.0.0</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

 

 

(ps) libs폴더에 테마를 위한 파일들을 넣어주고 "프로젝트 구조 > 종속 요소"에서 추가해준다. 개인적 취향...

idw-gpl.jar
0.70MB
JTattoo.jar
0.62MB
liquidlnf.jar
0.35MB
ojdbc6-11.2.0.4.jar
2.61MB
quaqua.jar
1.94MB

 

 

2. mybatis-config.xml에서 DB정보 생성

 

3. org.example.mapper > dbMapper 인터페이스 생성

package org.example.mapper;

import org.example.model.dbModel;
import java.util.List;

public interface dbMapper {
    List<dbModel> selectAll();
}

 

4. org.example.dto> dbDto생성 (레코드 형식이 편해서 클래스 대신 레코드를 주로 사용함)

package org.example.dto;

public record dbDto(
        String emp_no,
        String emp_x,
        String kornm_n,
        String hannm_n,
        String engnm_n,
        String res
) {
}

 

5. MyBatisUtil 생성

package org.example;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }

    public static SqlSession getSession() {
        return sqlSessionFactory.openSession();
    }
}

 

 

6. service > DbService 생성

DAO를 생성하는 경우가 많이 있는 것 같은데, 개인적으로는 복잡도가 낮아서 service만 만들어 구현해도 큰 어려움이 없는것 같다. DAO에 대한 개념도 없는 상태라, 프로젝트의 복잡도만 늘리는 것 같아서 Service만 구현했다.

package org.example.service;

import org.apache.ibatis.session.SqlSession;
import org.example.MyBatisUtil;
import org.example.dto.dbDto;
import org.example.mapper.dbMapper;

import java.util.List;

public class DbService {
    public List<dbDto> selectAll(){
        SqlSession session = MyBatisUtil.getSession();
        List<dbDto> list = null;

        try{
            dbMapper mapper = session.getMapper(dbMapper.class);
            list = mapper.selectAll();
        } catch (Exception ex){
            ex.printStackTrace();
        } finally {
            session.close();
        }
        return list;
    }
}

 

 

7. resources > mapper > dbMapper.xml 생성

Spring에서 사용하던 Mybatis와 동일하게 생성

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.example.mapper.dbMapper">
    <select id="selectAll" resultType="org.example.model.dbModel">
        select emp_# as emp_no,
        emp_x,
        kornm_n,
        hannm_n,
        engnm_n,
        res_#1 as res
        from temp a
        where a.kornm_n='김동개'
    </select>
</mapper>

 

8. org.example.view > MainView.java 생성

package org.example.view;

import org.example.dto.dbDto;
import org.example.service.DbService;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

public class MainView extends JFrame {
        DbService dbService = new DbService();

        JFrame f1 =new JFrame();    // Main Frame
        JMenuBar mb = new JMenuBar(); // 메뉴바
        JPanel sidePanel = new JPanel(); // 사이드 패널
        JPanel contentPanel = new JPanel(); // 컨텐츠 패널
        JPanel footerPanel = new JPanel();  // 푸터 패널
        JButton jb1 = new JButton("search"); // 버튼 초기화
        JButton jb2 = new JButton("insert"); // 버튼 초기화
        JButton jb3 = new JButton("delete"); // 버튼 초기화

//      JTable data_table = new JTable(); //테이블 생성시에는 초기값과 헤더를 넣어줘야한다. 
//        이 작업은 초기 화면 생성하는 함수에 넣어주기 위해, 아래와 같이 null로 우선 생성한다.
        JTable data_table = null;

        public void set_style(Component target){
            // 스타일 적용(Look & Feel)
            try{
                UIManager.setLookAndFeel ("com.birosoft.liquid.LiquidLookAndFeel"); 	//Liquid
            }catch(Exception e){
                System.out.println(e + "오류 발생");
            }
            SwingUtilities.updateComponentTreeUI(target) ;
        }

        public void createFrame(){
            // Main Frame 세팅
            f1.setSize(1024,760);//크기
            f1.setDefaultCloseOperation(f1.EXIT_ON_CLOSE);
            f1.setLocationRelativeTo(null);

            // 스타일 적용
            f1.setDefaultLookAndFeelDecorated(true);
            set_style(f1);

            // 아이콘 적용
            Image icon = Toolkit.getDefaultToolkit().getImage("D:\\7_System_dev2\\4_Java\\01_gui\\src\\icon.png");
            f1.setIconImage(icon);

            // 레이아웃 적용
            BorderLayout bl = new BorderLayout();
            f1.setLayout(bl);

            // 화면 요소 생성 및 추가
            createMenu();
            createSidePanel();
            createContentPanel();
            createFooter();

            f1.add(mb, BorderLayout.NORTH);
            f1.add(sidePanel, BorderLayout.WEST);       // f1라는 프레임에 sidePanel추가
            f1.add(contentPanel, BorderLayout.CENTER);  // f1라는 프레임에 contentPanel추가
            f1.add(footerPanel, BorderLayout.SOUTH);    // f1라는 프레임에 FooterPanel추가

            f1.setTitle("Frame Test");//제목
            f1.setVisible(true);//생성
        }

        // 메뉴바
        public void createMenu(){
            JMenu fileMenu = new JMenu("File");
            fileMenu.add(new JMenuItem("New"));
            fileMenu.add(new JMenuItem("Open"));
            fileMenu.add(new JMenuItem("Preferences"));

            mb.add(fileMenu);
            mb.add(new JMenu("Edit"));
            mb.add(new JMenu("About"));
            mb.add(new JMenu("Help"));
            setJMenuBar(mb);
        }

        // 사이드 패널
        public void createSidePanel(){
            sidePanel.setPreferredSize(new Dimension(100, 300)); // 사이드패널 사이즈 조절
            sidePanel.setBorder(BorderFactory.createEmptyBorder(15 , 10, 10 , 10));
//            sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));

            sidePanel.add(jb1);
            sidePanel.add(jb2);
            sidePanel.add(jb3);

            set_style(sidePanel);

            jb1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    data_mapping();

                    // 패널 갱신
                    contentPanel.revalidate();
                    contentPanel.repaint();
                }
            });
        }

        // Contents 패널
        public void createContentPanel(){
            contentPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
            contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
            JLabel Headline = new JLabel("Swing Table Data with Styles");
            Font f = new Font("고딕", Font.BOLD,20);
            Headline.setFont(f);
            contentPanel.add(Headline);

            // 테이블 준비
            String[] header = {"EMP No", "Name"};
            String[][] contents = {{"",""},{"",""},{"",""}};
            data_table = new JTable(contents, header);
            Font font = new Font("고딕", Font.PLAIN,12);
            data_table.setFont(font);
            contentPanel.add(new JScrollPane(data_table), BorderLayout.CENTER);
			// JScrollPane(data_table)에 넣어주지 않으면 header가 나타나지 않는다.
            set_style(contentPanel);
        }

        // Footer
        public void createFooter(){
            footerPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
            footerPanel.setBackground(Color.orange);
            JLabel Footer = new JLabel("Copyright by Wilkyway");
            footerPanel.add(Footer);

            // set_style(footerPanel);
        }

        public void data_mapping() {
            List<dbDto> models = dbService.selectAll();

            int i=0;
            for (dbDto model : models) {
                System.out.println("ID: " + model.emp_no() + ", Name: " + model.kornm_n());
                data_table.setValueAt(model.emp_no(),i,0);
                data_table.setValueAt(model.kornm_n(),i,1);
                i++;
            }
        }

}

 

 

8. Main.java

package org.example;
import org.example.view.MainView;

public class Main {

    public static void main(String[] args) {
        MainView mp = new MainView();
        mp.createFrame();
    }
}

 

 

<결과>

반응형
반응형

1. Tailwind CSS 와 PostCSS

npm install tailwindcss postcss autoprefixer gatsby-plugin-postcss
 

2. Tailwind CSS 초기화

npx tailwindcss init

tailwind.config.js 파일이 생성됨

3. PostCSS 설정

프로젝트 루트 디렉토리에 postcss.config.js 파일을 생성한다.

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

 

4. Gatsby 설정파일에 PostCSS 플러그인 추가

gatsby-config.js

module.exports = {
  ...
  plugins: [
    `gatsby-plugin-postcss`,
    ...

 

5. Global Style 파일 생성 (src/tailwind.css)

@tailwind base;
@tailwind components;
@tailwind utilities;

6. Global CSS 를 gatsby-browser.js에 추가

/**
 * Implement Gatsby's Browser APIs in this file.
 *
 * See: https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/
 */

// You can delete this file if you're not using it
import "./src/tailwind.css";

7. PurgeCSS 설정(Optional but Recommended for Production)

옵셔널이라고 되어있는데, 이게 되어야 정상 작동함.

/** @type {import('tailwindcss').Config} */

module.exports = {
  purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
반응형
반응형

1. next.config.mjs 수정

 

- 위와 같은 package.json 이 있다고 할 때, "npm run build" 를 하면 .next 폴더가 만들어지는데, next.config.mjs파일을 아래와 같이 수정해서 out파일을 배포하도록 설정을 바꿔줘야함.

 - 이미지 등의 경로를 제대로 인식할 수 있도록 basePath를 설정합니다.  [Next.js 의 모든 URL 앞에 추가되는 기본 경로를 설정]

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  basePath: '',
  images: {
    unoptimized: true,
  },
};

export default nextConfig;

 

예전에는 next build 후 out폴더에 static 파일들을 생성하도록 next export 명령어도 했어야 했던 것 같은데, 이번 14버전에서는 next export 대신 config파일에서 output: 'export' 를 설정해주는 것만으로도 작동합니다.

 

.next폴더와 out폴더 두개가 모두 생성되는데, netlify에 배포하는 폴더는 out 폴더입니다. 

 

2. Nelify플러그인 설치

무슨 역할을 하는지는 모르겠지만, 이것도 설치해야한다고 합니다.

npm install @netlify/plugin-nextjs

 

3. netlify.toml 생성

[build]
  command = "npm run build"
  publish = "out"

[[plugins]]
  package = "@netlify/plugin-nextjs"

 

 

이미지는 나왔는데, CSS가 아직 제대로 적용이 안되었네요. 조금 더 검토해봐야겠습니다.

 

오늘은 여기까지!

반응형
반응형

최신 오라클  라이브러리가 cx_Oracle에서 oracledb 변경되었다.

 

Insert

# Plan MH 일괄 추출
from datetime import datetime

import oracledb
import os


os.putenv('NLS_LANG', '.UTF8')
now = datetime.today()

# DB연결
conn = oracledb.connect(user='myuser', password='1234', dsn='abcd.abcde.com:1526/abcd')
cursor = conn.cursor() #지시자 생성

query_str = "insert into SOME_TABLE values (:1,:2,:3,:4,:5,:6,:7,:8)"
data = ('20240125','AAAA','BBBB','1400350','CCCC','2',now,'DDDD')
cursor.execute(query_str,data)
conn.commit()

conn.close()
반응형

+ Recent posts