본문 바로가기
프로그램/PWA

[PWA] 3장 스프링부트 프로젝트 생성

by cbwstar 2024. 1. 31.
728x90
반응형

3장 스프링부트 프로젝트 생성

3.1  push 알리미 기능 프로젝트 생성

spring부트 실행하여 File -> New -> Spring Starter Project

위와 같이 입력후 Next

DB는 테스트 하기 좋은 H2 메모리 DB를 선택 Spring Web, Lombok, 웹페이지는 Thymeleaf선택 JPA를 사용할꺼라서 Spring Data JPA 선택 Spring Boot DevTools는 개발할때 소스에 변경 사항이 있을경우 자동 재기동을 시켜주는 편리한 기능이 있어서 선택 하여 준다.

Finish를 눌러 준다.

프로젝트가 위와 같은 구조로 생성이 되었다.

일단 환경 설정 부터 해보자

src/main/resources 밑에 application.properties 파일을 yaml 형식으로 확장자를 변경한다.

application.yaml로 

yaml 파일은 입력할때 형식이 있다. 자릿수를 꼭 맞추어 주어야 에러가 없다.계층적으로 입력할때  2자리 스페이스를 입력후 입력을 해야 한다.yaml 형식이나 properties 에 입력하나 사용 방법은 동일한데 yaml 파일을 사용하면 중복 입력을 안해도 된다.

예를 들어 properties 파일에 다음과 같이 db접속 환경을 입력한다고 하면 이렇게 입력을 해야 한다.

 

datasource.driver-class-name=org.h2.Driver

datasource.url = jdbc:h2:mem:pwadb

datasource.username = sa

datasource.password = 

이렇게 입력을 해야 하지만 yalm 형식으로 입력하면 스페이스 2칸 입력후 중복되는 부분은 입력 할 필요 없이 입력하면 된다.

  datasource:

    driver-class-name: org.h2.Driver

    url: jdbc:h2:mem:pwadb

    username: sa

    password:

이런식으로 계층을 확실하게 스페이스 2칸 띄워줘야 인식을 하고 에러가 안난다.

application.yaml 파일에 정보를 다음과 같이 입력한다.

server:
  port: 8081
  servlet:
    context-path: /
    encoding:
      charset: UTF-8
      enabled: true
      force: true
  error:
    include-exception: true
    include-stacktrace: always
  tomcat:
    uri-encoding: UTF-8

spring:
  thymeleaf:
    prefix: classpath:templates/thymeleaf/
    suffix: .html
    cache: false
  profiles:
    active: local
   
# h2db    
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:pwadb
    username: sa
    password:
   
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: create  #update create none
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
      use-new-id-generator-mappings: false
    show-sql: true
    properties:
      hibernate.enable_lazy_load_no_trans: true 
      hibernate.format_sql: true
     
  servlet:
    multipart:
      enabled: true
      max-file-size: 2MB
    encoding:
      charset: UTF-8
      enabled: true
      force: true
     
  logging:
  level:
    org.springframework.web : off
    sql: error
    jdbc: off
    jdbc.sqlonly: debug
  file : ${user.home}/logs/product.log
  file.max-history: 9999999
  file.max-size : 100MB
 

server 부분에 톰캣에서 실행되는 웹서버 주소를 8081로 설정을 하였다 root context를 /로 설정을 하였기 때문에 내장톰캣 서버 기동시 url 주소는 http://localhost:8081 롤 접속을 하면 된다.

스프링 부트에서는  jsp를 지양하고 thymeleaf 형식의 문법을 사용하는 html 페이지를 사용한다. suffix에 확장자를 html로 설정을 하였다.

h2db를 사용할 거라서 datasource 부분을 h2 접속 정보를 입력하였다. 이 부분을 다을 데이터베이스 사용할거면 정보를 바꾸어 주면 된다. mysql이나 postgreSql이 jpa를 지원하는 어떠한 db라도 상관이 없다.

jpa 설정 부분에서 ddl-auto에서 create로 설정을 톰캣서버 기동시 기존에 있던 테이블을 삭제하고 새로 테이블을 생성한다.

update로 설정을 하면 변경된 부분만 db에 반영한다. 예를 들어 컬럼정보가 추가 되면 db에 컬럼정보가 추가 된다. 추가된거만 반영이 된다. 삭제된거는 반영이 안된다.

운영시에는 none로 하고 운영을 해야 한다. none으로 설정을 하면 db에 반영을 안한다.

운영시에 create로 하면 운영중인 db 테이블이 다 삭제 되고 다시 만들기 때문에 기존에 데이터가 다 날아간다. 운영시에는 모조건 none로 한다.

servlet 부분은 첨부파일이 있는경우 최대 첨부파일 사이즈를 설정한다.

logging 부분은 log파일 설정인데 logback을 사용할 거라서 굳이 설정을 안해 줘도 상관없다.

resource폴더 밑에 logback-local.properties 파일을 하나 생성한다. 로그파일이 저장되는 경로를 설정한다.

log.config.path=/logs/local           /* 로그파일 저장경로 */
log.config.filename=local_log         /* 로그파일 이름 */

logback-local.properties 파일에 위의 내용을 입력한다.

resource 폴더에 logback-spring.xml 파일을 생성한다.

아래의 내용을 붙여 넣는다.

 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 60초마다 설정 파일의 변경을 확인 하여 변경시 갱신 -->
<configuration scan="true" scanPeriod="60 seconds">
<!--springProfile 태그를 사용하면 logback 설정파일에서 복수개의 프로파일을 설정할 수 있다.-->
<springProfile name="local">
<property resource="logback-local.properties"/>
</springProfile>
  <springProfile name="dev">
  <property resource="logback-dev.properties"/>
  </springProfile>
 
  <!--Environment 내의 프로퍼티들을 개별적으로 설정할 수도 있다.-->
  <springProperty scope="context" name="LOG_LEVEL" source="logging.level.root"/>
 
  <!-- log file path -->
  <property name="LOG_PATH" value="${log.config.path}"/>
  <!-- log file name -->
  <property name="LOG_FILE_NAME" value="${log.config.filename}"/>
  <!-- err log file name -->
  <property name="ERR_LOG_FILE_NAME" value="err_log"/>
  <!-- pattern -->
  <property name="LOG_PATTERN" value="%-5level %d{yy-MM-dd HH:mm:ss}[%thread] [%logger{0}:%line] - %msg%n"/>
  <!-- Console Appender -->
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  <pattern>${LOG_PATTERN}</pattern>
    </encoder>
  </appender>
  <!-- File Appender -->
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 파일경로 설정 -->
  <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
  <!-- 출력패턴 설정-->
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  <pattern>${LOG_PATTERN}</pattern>
  </encoder>
  <!-- Rolling 정책 -->
 
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  <!-- .gz,.zip 등을 넣으면 자동 일자별 로그파일 압축 -->
    <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
  <!-- 파일당 최고 용량 kb, mb, gb -->
  <maxFileSize>10MB</maxFileSize>
  </timeBasedFileNamingAndTriggeringPolicy>
  <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
    <maxHistory>30</maxHistory>
    <!--<MinIndex>1</MinIndex> <MaxIndex>10</MaxIndex>-->
    </rollingPolicy>
    </appender>
    <!-- 에러의 경우 파일에 로그 처리 -->
    <appender name="Error" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>error</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
  </filter>
    <file>${LOG_PATH}/${ERR_LOG_FILE_NAME}.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>${LOG_PATTERN}</pattern>
    </encoder>
      <!-- Rolling 정책 -->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- .gz,.zip 등을 넣으면 자동 일자별 로그파일 압축 -->
      <fileNamePattern>${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- 파일당 최고 용량 kb, mb, gb -->
        <maxFileSize>10MB</maxFileSize>
          </timeBasedFileNamingAndTriggeringPolicy>
          <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
          <maxHistory>60</maxHistory>
          </rollingPolicy>
      </appender>
      <!-- root레벨 설정 -->
    <root level="${LOG_LEVEL}">
    <appender-ref ref="CONSOLE"/>
    <appender-ref ref="FILE"/>
    <appender-ref ref="Error"/>
    </root>
    <!-- 특정패키지 로깅레벨 설정 -->
      <logger name="org.apache.ibatis" level="INFO" additivity="false">
      <appender-ref ref="CONSOLE"/>
      <appender-ref ref="FILE"/>
      <appender-ref ref="Error"/>
      </logger>
</configuration>
 

 

위에서 application.yml 파일에서 

  profiles:

    active: local  

로 설정한 부분이 있다. local에서 개발시에는 active를 local로 설정을 하고 배포시에는 active를 dev난 prod로 설정을 하면 설정에 따라서 logback-spring.xml파일에서 springProfile name=”local” 부분이 있다.

active 설정 모드에 따라서 logback-local.properties 파일을 읽어 오게된다.

이제 로그 파일까지 설정을 하였다.

resource폴더에 pwa.properties 파일을 생성후에

publicKey = BNzzfdcBcThU27FcGve6F3GF6He2Fro82ZMuOLga9fukatLMlaKB6GdO-82loi6W4iGdPQZAp_4HLgST8z5of_E
privateKey = yzZ8xvvhiM50HlTsDLCwiofkCyOypb-ZTkqdvpwyz7c

publicKey와 privateKey를 입력한다. 이키는 pwa에서 push 알림을 보낼때 사용되는 공개키와 비밀키이다. 키는 이 프로젝트가 끝날때즘 새로운 키를 생성해야 한다. privateKey는 공개 되어서는 안되는 키이다.

 

제대로 따라 했다면 resource 폴더가 위와 같은 그림이 되어야 한다.

build.gradle 파일을 열어서 push 기능을 만들기 위해 의존성 라이브러리를 몇개 추가 하자tarter', version: '1.7.1'

implementation group: 'nl.martijndwars', name: 'web-push', version: '5.1.1'
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.68'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.3'
implementation group: 'com.github.gavlyukovskiy', name: 'p6spy-spring-boot-starter', version: '1.7.1'

 

web-push', version: '5.1.1' : web-push 를 사용할수 있게 해주는 lib다

'bcprov-jdk15on', version: '1.68' : security 보안 관련 lib다

com.fasterxml.jackson.core : json 형식으로 변환해 주는 lib다

p6spy-spring-boot-starter : 쿼리 로그 찍힐때 파라미터 정보를 출력하게 해준다.

 

build.gradle 전체 셋팅 파일

plugins {
id 'org.springframework.boot' version '2.5.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}

group = 'pwa-push'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'nl.martijndwars', name: 'web-push', version: '5.1.1'
    implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.68'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.3'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.3'
    implementation group: 'com.github.gavlyukovskiy', name: 'p6spy-spring-boot-starter', version: '1.7.1'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
useJUnitPlatform()
}

 

여기까지 셋팅이 끝났으면 스프링부트 서버가 에러 없이 잘 실행이 되는지 실행을 해 보자.

프로젝트에서 마우스 오르쪽 버튼을 클릭하여 Run As를 선택후 Spring Boot App을 실행 시켜서 서버를 구동하자.

 

 

Boot Dashboard에서도 선택하여 구동시킬수 있다.

실행을 시키면 Console탭에 실행 로그가 출력이 된다.

Console 탭에 정상적으로 로그가 에러없이 기동이 되었다

크롬 브라우저를 띄워서 실행이 되는지 확인을 해보자

 

 

http://127.0.0.1:8081 로 접속을 하면 위와 같이 화면이 뜨면 정상적으로 기동이 된것이다.

아직 아무 페이지도 만들지 않았기 때문에 스프링 부트 자체에서 보여주는 에러페이지가 출력이 된 것이다.

 

728x90
반응형

댓글



"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

loading