ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링부트로 간단 Micro Service 구축하기
    웹개발/Micro Service Architecture 2019. 3. 21. 11:08
    https://jojoldu.tistory.com/
    3) 스프링부트로 웹 서비스 출시하기 - 3. SpringBoot & Handlebars로 화면 만들기  (16) 2018.01.04
    2) 스프링부트로 웹 서비스 출시하기 - 2. SpringBoot & JPA로 간단 API 만들기  (24) 2017.12.28
    1) 스프링부트로 웹 서비스 출시하기 - 1. SpringBoot & Gradle & Github 프로젝트 생성하기  (6) 2017.12.24


    링크 포스트의 위 글을 그대로 따라하면서 간단한 서비스를 구축했다.

    기본적인 구축방법은 링크포스트에 자세히 나와있다.

    따라하면서 쭉 별 문제 없이 진행해서 원하는 결과를 얻었지만 몇가지 짚고 넘어가야할 이슈들 정리하려함..



    메인 페이지 생성

    핸들바를 썼는데 스프링부트에서 핸들바 플러그인이 없어서 컴파일이 안되었다.

    하지만 프로젝트에서 hbs를 인식하는데는 문제가 없었다.


    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import com.test.service.PostsService;
    import lombok.AllArgsConstructor;
    
    @Controller
    @AllArgsConstructor
    public class WebController {
    
    	  private PostsService postsService;
    
    	    @GetMapping("/")
    	    public String main(Model model) {
    	        model.addAttribute("posts", postsService.findAllDesc());
    	        return "main";
    	    }
    }
    


    컨트롤러의 리턴값이 main 이면 알아서 main.hbs를 잘 찾는다



    게시판 만들기

    링크한 포스팅을 다 따라하면 간단한 게시판이 만들어진다
    DB를 따로 구축안해도 프로젝트가 실행될때마다 로컬에 가상디비가 생긴다
    resources 아래에 sql파일을 두면
    프로젝트가 실행될때마다 sql파일안의 쿼리를 실행한다!





    application.yml

    server:
      port: 9999
    
    spring:
      profiles:
        active: local # 기본 환경 선택
    
    # local 환경
    ---
    spring:
      profiles: local
      datasource:
        data: classpath:data-h2-ansi.sql # 시작할때 실행시킬 script
        #sql-script-encoding: UTF-8
        #continue-on-error: true
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: create-drop
          use-new-id-generator-mappings: false
          #connection: charSet:UTF-8
      h2:
        console:
          enabled: true
    


    웹페이지에서 게시판에 입력하는 것은 잘된다.

    웹에서 저렇게 입력하면 스크립트가 가상DB로 insert시킨다



    웹으로 입력화면


    웹으로 입력후 출력화면 : 게시판 목록


    인코딩 문제

    웹에서 입력하거나 h2콘솔을 사용해서 한글을 입력하는데에는 문제가 없었다.

    그러나 초기실행 쿼리문이 들어있는 sql파일(data.sql)에 한글을 입력하면 DB에 깨져서 들어가는 것이었다 ㅠㅠ

    이게 제일 난감한 문제였는데 여러가지 방법을 시도해보았다.


    data.sql

    INSERT INTO POSTS (title, author, content, created_date, modified_date) 
    VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now());
    
    INSERT INTO POSTS (title, author, content, created_date, modified_date) 
    VALUES ('테스트22222', 'test2@gmail.com', 'testcontent22222', now(), now());
    

    POSTS테이블에 2열을 삽입하라는 쿼리인데 프로젝트 실행시마다 자동으로 실행된다.



    1. application.yml에 설정추가하기 -> 실패

    spring:
      profiles: local
      datasource:
        data: classpath:data-h2-ansi.sql # 시작할때 실행시킬 script
        sql-script-encoding: UTF-8
        continue-on-error: true
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: create-drop
          use-new-id-generator-mappings: false
          connection: charSet:UTF-8
    

    sql-script-encoding: UTF-8

    sql파일의 인코딩을 UTF-8로 하겠다는 뜻

    https://code.chamo.de/2017/04/21/spring-boot-jpa-encoding-data-sql/


    여기서 발견했는데 파일인코딩이 UTF8이 아니어도 UTF8로 바꿔주겠다 그런것은 아닌거같다.

    적용하는것과 안하는것의 차이가 없었다;;


    continue-on-error: true

    data.sql의 인코딩이 ANSI또는 UTF-8 BOM없음이 아니면 초기 쿼리실행에서 에러가난다

    entityManagerFactory라는 빈 생성 실패라는데 잘 모르겠다;;

    continue-on-error는 이렇게 에러에도 불구하고 계속 진행할지 여부를 설정하는 값이다.

    빈 생성이 실패해도 data.sql에서 첫줄은 건너뛰고 2번째줄부터 실행했다.


    data.sql 인코딩문제로 파일을 못읽었을때 에러로그

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data-h2-utf8.sql]: INSERT INTO POSTS (title, author, content, created_date, modified_date) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now()); nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "INSERT[*] INTO POSTS (TITLE, AUTHOR, CONTENT, CREATED_DATE, MODIFIED_DATE) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', NOW(), NOW()) "; SQL statement:
    INSERT INTO POSTS (title, author, content, created_date, modified_date) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now()) [42000-197]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at com.test.Application.main(Application.java:15) [main/:na]
    Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data-h2-utf8.sql]: INSERT INTO POSTS (title, author, content, created_date, modified_date) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now()); nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "INSERT[*] INTO POSTS (TITLE, AUTHOR, CONTENT, CREATED_DATE, MODIFIED_DATE) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', NOW(), NOW()) "; SQL statement:
    INSERT INTO POSTS (title, author, content, created_date, modified_date) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now()) [42000-197]
    	at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:509) ~[spring-jdbc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:238) ~[spring-jdbc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48) ~[spring-jdbc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:210) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.initSchema(DataSourceInitializer.java:123) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.onApplicationEvent(DataSourceInitializerInvoker.java:93) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.onApplicationEvent(DataSourceInitializerInvoker.java:37) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:98) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.postProcessAfterInitialization(DataSourceInitializedPublisher.java:88) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:429) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	... 15 common frames omitted
    Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "INSERT[*] INTO POSTS (TITLE, AUTHOR, CONTENT, CREATED_DATE, MODIFIED_DATE) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', NOW(), NOW()) "; SQL statement:
    INSERT INTO POSTS (title, author, content, created_date, modified_date) VALUES ('테스트11111', 'test1@gmail.com', 'testcontent11111', now(), now()) [42000-197]
    	at org.h2.message.DbException.getJdbcSQLException(DbException.java:357) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.message.DbException.get(DbException.java:179) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.message.DbException.get(DbException.java:155) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.message.DbException.getSyntaxError(DbException.java:203) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.command.Parser.getSyntaxError(Parser.java:548) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.command.Parser.parsePrepared(Parser.java:506) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.command.Parser.parse(Parser.java:335) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.command.Parser.parse(Parser.java:311) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.command.Parser.prepareCommand(Parser.java:278) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.engine.Session.prepareLocal(Session.java:611) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.engine.Session.prepareCommand(Session.java:549) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1247) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:217) ~[h2-1.4.197.jar:1.4.197]
    	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205) ~[h2-1.4.197.jar:1.4.197]
    	at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-3.2.0.jar:na]
    	at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-3.2.0.jar:na]
    	at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:488) ~[spring-jdbc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    	... 31 common frames omitted
    

    connection: charSet: UTF-8

    이거는 DB의 캐릭터셋이 UTF-8임을 설정하는 거같은데,..

    별 변화가 없었다.




    2. sql파일의 인코딩을 특정방식(UTF-8 BOM없음)으로하기 -> 성공

    data.sql을 인코딩 방식을 다르게 해서 시도했다.


    ANSI : 메모장 기본설정인데 쿼리실행은 되지만 한글이 깨져서 인서트된다 ㅠㅠ

    UTF-8 : 프로젝트 시작할때 에러발생한다. 파일을 읽는데 문제가 생긴다.

    UTF-8(BOM없음) : 파일 읽기 정상. 한글입력 정상

    Unicode : 메모장에 있는 설정인데 이것도 프로젝트 시작시 파일읽기에 문제가 생긴다. 



    data.sql 파일 생성법

    인코딩변환은 notepad ++에서 ~로 변환을 클릭해서 다른파일로 이름바꿔서 저장했다




    왜 되는지 왜 안되는지 아직은 잘 모른다!

    ㅠㅠ알아봐야함..

     -  UTF-8, UTF-8 BOM차이


    아래링크 포스트에서 BOM있는 UTF8은 보이지 않게 어떤 명시가 있다는데

    그게 걸리적거려서 에러가 났을수있다 하는데 아마도 그런듯..


    UTF변환 시, BOM에 대해서.





    댓글

Designed by Tistory.