개발자입니다
[비트캠프] 89일차(19주차2일) - Spring Framework(톰캣 삽입), Spring Boot(2.7.x javaEE 적용, Lombok, 3.x jakartaEE 적용, Undertow 서블릿 컨테이너 적용) 본문
[비트캠프] 89일차(19주차2일) - Spring Framework(톰캣 삽입), Spring Boot(2.7.x javaEE 적용, Lombok, 3.x jakartaEE 적용, Undertow 서블릿 컨테이너 적용)
끈기JK 2023. 3. 14. 17:54
### 65. 프로젝트에 서블릿 컨테이너(예:톰캣) 삽입하기
central.sonatype.com 에서 "tomcat-embed-jasper" 검색해서 9.0.73 버전(javaEE) 코드 복사해서 build.gradle 붙인 후 $ gradle eclipse 한다.
Referenced Library 에 다음 추가된다.
### 65. 프로젝트에 서블릿 컨테이너(예:톰캣) 삽입하기
- 프로젝트에 톰캣을 삽입하여 구동하는 방법
build.gradle 에 임베디드 톰캣 서버 코드 추가해서 $ gradle eclipse 한다.
plugins {
id 'eclipse-wtp' // 'eclipse' 플러그인이 자동 포함됨
id 'war' // 웹 애플리케이션 관련 명령을 사용할 수 있다.
}
// CLI 환경에서 'build' 작업을 수행할 때 사용하는 설정
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
sourceCompatibility = '17'
targetCompatibility = '17'
}
// 웹 애플리케이션 배포 파일(.war)을 만들 때 사용할 기본 파일 이름을 설정한다.
// 이 이름은 웹 애플리케이션 context root 경로로도 사용된다.
war {
archiveBaseName = "web"
}
// 'eclipse' 플러그인 설정:
eclipse {
// => eclipse 프로젝트 이름 설정하기
project {
name = "myapp-server"
}
// => eclipse IDE 설정하기
jdt {
sourceCompatibility = 17
targetCompatibility = 17
javaRuntimeName = "JavaSE-17"
}
// 자바 웹 개발 도구에서 사용할 값을 설정한다.
wtp {
facet {
//you can add some extra wtp facets or update existing ones; mandatory keys: 'name', 'version':
facet name: 'jst.java', version: '17'
facet name: 'jst.web', version: '4.0'
}
component {
//you can configure the context path:
//contextPath = '/web'
//you can configure the deployName:
//deployName = 'web'
}
}
}
repositories {
mavenCentral()
}
dependencies {
// Spring WebMVC 라이브러리
// => spring-web, spring-context에 의존한다.
// => JavaEE8(Servlet 4.0.1) 버전의 서블릿 컨테이너를 실행할 경우 5.x 버전을 사용해야 한다.
implementation 'org.springframework:spring-webmvc:5.3.25'
// Spring Web 라이브러리
//implementation 'org.springframework:spring-web:6.0.5'
// Spring IoC 컨테이너
//implementation 'org.springframework:spring-context:6.0.5'
// Google JSON 라이브러리
implementation 'com.google.code.gson:gson:2.10.1'
// MariaDB JDBC 드라이버
implementation 'org.mariadb.jdbc:mariadb-java-client:3.1.2'
// Mybatis SQL Mapper 라이브러리
implementation 'org.mybatis:mybatis:3.5.11'
// Mybatis-Spring 연동 라이브러리
implementation 'org.mybatis:mybatis-spring:3.0.1'
// Spring JDBC 연동 라이브러리
implementation 'org.springframework:spring-jdbc:5.3.25'
// Servlet API 라이브러리
// - 이 라이브러리는 개발하는 동안만 사용한다.
// 즉 컴파일하거나 빌드할 때만 사용한다.
// - 배포 파일에는 이 라이브러리를 제외시킨다.
// 왜? 서블릿 컨테이너에 포함되어 있기 때문이다.
providedCompile 'javax.servlet:javax.servlet-api:4.0.1'
// JSTL 라이브러리
implementation 'javax.servlet:jstl:1.2'
// Tiles 라이브러리
implementation 'org.apache.tiles:tiles-jsp:3.0.8'
// Thymeleaf 라이브러리
implementation 'org.thymeleaf:thymeleaf-spring5:3.1.1.RELEASE'
// Log4j 2.x 라이브러리
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
// MappingJackson2HttpMessageConverter 가 사용할 라이브러리
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
// multipart/form-data 처리 라이브러리
// => Servlet 3.0 API에서 제공하는 멀티파트 처리 기능을 사용한다면 이 라이브러리는 필요없다.
//implementation 'commons-fileupload:commons-fileupload:1.5'
// 임베디드 톰캣 서버
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper:9.0.73'
implementation 'com.google.guava:guava:31.1-jre'
testImplementation 'junit:junit:4.13.2'
}
myapp 에 App.java 생성하고 아래 코드 입력한다.
package bitcamp.myapp;
import java.io.File;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
public class App {
public static void main(String[] args) {
System.out.println("비트캠프 프로젝트!");
// 톰캣 서버를 구동시키는 객체를 준비한다.
Tomcat tomcat = new Tomcat();
// 서버의 포트 번호를 설정한다.
tomcat.setPort(8080);
// 톰캣 서버를 실행하는 동안 사용할 임시 디렉토리를 설정한다.
tomcat.setBaseDir("temp");
// 서버의 연결 정보를 설정한다.
Connector connector = tomcat.getConnector();
// 클라이언트와 데이터를 주고 받을 때 적용할 문자 집합을 설정한다.
connector.setURIEncoding("UTF-8");
// 웹 애플리케이션의 context path와 배치 디렉토리를 설정한다.
tomcat.addWebapp(
"/web", // 웹 애플리케이션 context path
new File("./src/main/webapp/").getAbsolutePath());
try {
// 톰캣 서버를 실행한다.
tomcat.start();
} catch (LifecycleException e) {
e.printStackTrace();
}
// 톰캣 서버가 종료될 때까지 JVM을 끝내지 않고 기다린다.
tomcat.getServer().await();
}
}
Eclipse 의 Servers 에 있는 톰캣 서버 삭제해도 된다.
### 66. SpringBoot(2.7.x) 적용하기
.gitignore 파일 맨 밑에 upload/ 추가해서 git 저장소에 업로드 되지 않게 한다.
spring.io 의 spring initializr 들어가서 아래처럼 입력하고 Dependencies 선택한다. EXPLORE 클릭 한다.
build.gradle 에서 필요한 코드 복사한다.
### 66. SpringBoot(2.7.x) 적용하기
- SpringBoot 사용법
SpringBoot 에 필요한 코드 붙여넣고 $ gradle eclipse 한다.
plugins 붙여넣는다.
group 및 version 붙여넣는다.
배포 불필요하므로 war 삭제한다.
eclipse 안의 wtp (Web Tools Platform) 삭제한다.
configurations 코드 붙여넣는다.
dependencies 안의 Spring WebMVC, Google json, jdbc, Servlet, JSTL, Tiles, Thymeleaf, log4j, jackson, embed tomcat, guava, junit 삭제한다.
spring boot에 jdbc, json, log4j 및 tomcat 내장되어 있다.
mybatis, mariadb 는 코드 변경한다.
plugins {
id 'eclipse'
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'bitcamp'
version = '0.0.1-SNAPSHOT'
// CLI 환경에서 'build' 작업을 수행할 때 사용하는 설정
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
sourceCompatibility = '17'
targetCompatibility = '17'
}
eclipse {
project {
name = "myapp-server"
}
jdt {
sourceCompatibility = 17
targetCompatibility = 17
javaRuntimeName = "JavaSE-17"
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.0'
//compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
//annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
App.java 를 다음과 같이 바꾼다.
AppConfig.java, AdminConfig.java 의 인터셉터 부분만 가져와서 붙인다.
config 패키지 통째로 삭제한다.
package bitcamp.myapp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import bitcamp.myapp.web.interceptor.AdminCheckInterceptor;
import bitcamp.myapp.web.interceptor.AuthInterceptor;
@EnableTransactionManagement
@SpringBootApplication
public class App implements WebMvcConfigurer {
Logger log = LogManager.getLogger(getClass());
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
log.info("App.addInterceptors() 호출됨!");
registry.addInterceptor(new AuthInterceptor()).excludePathPatterns("/auth/**");
registry.addInterceptor(new AdminCheckInterceptor()).addPathPatterns("/students/**");
registry.addInterceptor(new AdminCheckInterceptor()).addPathPatterns("/teachers/**");
}
}
src/main/resources 에 application.properties 파일 생성한다.
Log 수준, 포트 설정, DB 연결 설정, mybatis vo 지정하여 xml 파일에서 클래스 전체 경로 참조하지 않도록 함, 멀티파트 파일 크기 제한 지정한다.
# log
logging.level.root=info
logging.level.bitcamp.myapp.dao=debug
# server
server.port=8080
server.servlet.context-path=/web
# database
#spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/studydb
spring.datasource.username=study
spring.datasource.password=1111
# mybatis
mybatis.type-aliases-package=bitcamp.myapp.vo
#mybatis.mapper-locations=/bitcamp/myapp/mapper/*Mapper.xml
#*Dao 와 *Mapper.xml 이름을 같게 하면 코드 필요없다.
# web
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=200MB
다음 파일 삭제한다 : WEB-INF 의 web.xml, resources/bitcamp/myapp/config 의 jdbc.properties, log4j2.xml
dao 패키지의 모든 Dao 클래스에 @Mapper 붙인다. Mapper 파일을 Dao 와 이름을 같게한다. 그러면 mybatis 관련 코드 필요없다.
src/main/webapp 폴더를 resources 아래에 복사하고 이름을 static 으로 바꾼다.
URL 에서 /app 제거 할 것이므로 HTML, js 에 주소 수정해준다.
### 67. Lombok 적용하기
"lombok" 검색해서 사이트 들어간다. Install > IDEs > Eclipse 에 https://projectlombok.org/p2 복붙한다.
Eclipse 에서 Help > Install New Software 들어가서 붙여넣고 Add... 클릭한다.
아래 Lombok 체크한다. Contact all ~ 클릭하면 업데이트 안된게 전부 업데이트 되고나서 설치되므로 체크 해제한다.
Next 하다가 아래 창 나오면 Select All 선택하고 Trust Selected 클릭한다.
Eclipse 재시작하고 Board.java 에서 Outline 보면 만들지 않은 getter, setter 가 나온다.
build.gradle 에 아래 코드 입력하고 $ gradle eclipse 한다.
- 컴파일 시에만 Lombok 라이브러리를 사용하겠다.
- Lombok 라이브러리를 사용하여 컴파일 시에 코드를 생성하라. getter/setter, equals()/hashCode()
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
### 67. Lombok 적용하기
- Lombok 사용법
Lombok 적용 후 vo 객체의 getter, setter 삭제한다.
@Data 붙이면 적용된다.
package bitcamp.myapp.vo;
import java.sql.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import lombok.Data;
@Data
public class Board {
private int no;
private String title;
private String content;
private String password;
@JsonFormat(
shape = Shape.STRING,
pattern = "yyyy-MM-dd")
private Date createdDate;
private int viewCount;
private int writerNo;
private String writerName;
private Member writer;
private List<BoardFile> attachedFiles;
}
나머지 vo 도 동일하게 한다.
### 68. SpringBoot(3.x) 교체하기
### 68. SpringBoot(3.x) 교체하기
- Jakarta EE 사용법
spring.io initializr 에서 아래와 같이 설정한다.
build.gradle 에 아래 처럼 버전 변경하고 $ gradle eclipse 한다.
plugins {
id 'org.springframework.boot' version '3.0.4'
id 'io.spring.dependency-management' version '1.1.0'
}
dependencies {
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.0'
}
controller 패키지에 빨간불 뜨는데 import 패키지 이름이 달라서 이다.
해당 파일 들어가서 ctrl + shift + O 해서 import 패키지를 javax → jakarta 로 변경시킨다.
### 69. 서블릿 컨테이너 교체하기: Undertow 서블릿 컨테이너
### 69. 서블릿 컨테이너 교체하기: Undertow 서블릿 컨테이너
- SpringBoot의 서블릿 컨테이너를 교체하는 방법
build.gradle 의 spring-boot-starter-web 을 아래 처럼 변경한다.
implementation 은 함수로, 해당 라이브러리에서 tomcat 을 제외하고 undertow 를 넣는다.
implementation ('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-undertow'
추후 참고를 위해 App.java 에 Cross-Origin 관련 메서드 추가한다.
package bitcamp.myapp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import bitcamp.myapp.web.interceptor.AdminCheckInterceptor;
import bitcamp.myapp.web.interceptor.AuthInterceptor;
@EnableTransactionManagement
@SpringBootApplication
public class App implements WebMvcConfigurer {
Logger log = LogManager.getLogger(getClass());
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
log.info("App.addInterceptors() 호출됨!");
registry.addInterceptor(new AuthInterceptor()).excludePathPatterns("/auth/**");
registry.addInterceptor(new AdminCheckInterceptor()).addPathPatterns("/students/**");
registry.addInterceptor(new AdminCheckInterceptor()).addPathPatterns("/teachers/**");
}
// Cross-Origin 관련해서 기본 값 외에 추가로 설정할 게 있다면 이 메서드를 정의한다.
// 스프링부트가 시작되면 이 메서드를 호출하여 CrossOrigin을 설정할 것이다.
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5500", "http://127.0.0.1:5500")
.allowedMethods("*");
}
}
조언
*
과제
학습
eomcs-java\eomcs-web\app\src\main\resources\static\react