스프링

 

스프링부트 2.7.6   + mybatis + jsp +maven  기준으로  3.0.5 업그레이드 방법 

 

 

1단계 :

pc에 설치 된 자바 버전을 17이상으로  올려준다.

 

 

 

 

2단계 :

 pom.xml 이나 , build.gradle 에서  단순히  버전만 올리면 에러 뿐만 아니라 프로젝트 구조가 바뀌어서 힘들다.
따라서,  https://start.spring.io/ 사이트에서 기본적인  
샘플 프로젝트를 다운 받은 후  임포트 해서   이 프로젝트를 기준으로  업데이트할 프로젝트

파일들을  옮기는 방법을 추천한다. 
 

 

 

샘플 
https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.0.5&packaging=war&jvmVersion=17&groupId=com.example&artifactId=macaronics&name=sample&description=3.0%20%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C%20%EC%83%98%ED%94%8C&packageName=com.example.macaronics&dependencies=data-jdbc,mail,mustache,oauth2-client,security,validation,web,devtools,mybatis,mariadb,lombok,data-jpa,mysql

 

 

위와 같이 프로젝트에 사용한 기본  라이브러리를 설정 한 후 다운 받는다.

 

pom.xml 에서 다음 부분만 기존 프로젝트 있는 내용으로 변경 처리한다. 

  <groupId>com.example</groupId>
  <artifactId>macaronics</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>sample</name>
  <description>3.0 업그레이드 샘플</description>

 

 

 

 

 

3단계 :
 

 기존 프로젝트에서   파일들을 덮어씌운다.


1) src/main/java/이하파일들 덮어 씌우기

2)src/main/resources/이하파일들 덮어 씌우기

3)src/main/webapp/이하파일들 덮어 씌우기

 

 

 

 

4단계 :

아직 추가하지 않은 라이브러리 및  기타 3.0 에서 특화된  많은  오류사항이 보일텐데,

먼저,  javax.   를   이클립스 crtl +shfit +h , shift+shift 로 전체 파일을 jakarta. 포 변경한다.

 

javax.sql.DataSource  ,   javax.imageio.ImageIO   , javax.crypto.SecretKey 등은    jakarta 가 아니라 기존 그대로  javax 이다.

 

 

 

 

 

 

5단계 :

시큐리티 변경

 

Spring Security 변경
SecurityConfig에서 제거된 다음의 메서드를 변경해주어야 한다.

authorizeRequests() ➔ authorizeHttpRequests()
antMatchers() ➔ requestMatchers()
regexMatchers() ➔ RegexRequestMatchers()

 

 

@Configurable -> 스프링부트 3.0 이상 작동 안됨

 

@Configurable  사용하고 있다면  @Component 변경 처리한다.

 

다음과 같은  @Component 만 사용해도 작동 되는 것 같으나 세부적으로 살펴보지 않은관계로

 @EnableWebSecurity 과  @EnableMethodSecurity은 사용처리해 준다.

//@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) // secured 어노테이션 활성화
//@Configurable  -> 스프링부트 3.0 이상 작동 안됨
//@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록이 됩니다.
@Component
public class SecurityConfig  {

 

 

샘플 예 

	
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    	
        http.csrf().disable().cors().disable()
                .authorizeHttpRequests(request -> request
                        .dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
                         
                        
        		.requestMatchers(HttpMethod.GET, "/board/**").permitAll()
				.requestMatchers(HttpMethod.POST, "/board/**","/comment/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN", "ROLE_MANAGER")
				.requestMatchers(HttpMethod.DELETE, "/board/**" ,"/comment/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN", "ROLE_MANAGER")
				.requestMatchers(HttpMethod.PUT, "/board/**" ,"/comment/**").hasAnyAuthority("ROLE_ADMIN", "ROLE_MANAGER" ,"ROLE_USER")
			
			
				
				.requestMatchers("/", "/resources/**", "/loginForm/**", "/login/**", "/join/**", "/displayFile","/phoneCertification",
						"/emailAuthentication/send", "/findIdPassword/**","/like/list").permitAll()
                        
				
                )
                
                .formLogin(login -> login
                        .loginPage("/loginForm")
                        .loginProcessingUrl("/login")
                        .usernameParameter("userId")
                        .passwordParameter("password")
                        .defaultSuccessUrl("/", true)
                        .failureHandler(customFailureHandler) // 로그인 오류 실패 체크 핸들러
                        .permitAll()
                )
                .logout();

        return http.build();
    }

 

 

 

 

 

 

 

 

6단계 :

6. com.navercorp.lucy   라이브러리를 사용하고 있다면 오류가 나올텐데.

이것이 아직 업데이트 되지 않고 기존 javax 를 사용하고 있어서 이다.

다음과 같이 파일을 만들어 준다.

 

XssEscapeServletFilterUpdate

package net.macaronics.util.filter.navercorp;

import java.io.IOException;

import com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
@Component
public class XssEscapeServletFilterUpdate implements Filter {
	private XssEscapeFilter xssEscapeFilter = XssEscapeFilter.getInstance();

	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		chain.doFilter(new XssEscapeServletFilterWrapperUpdate(request, xssEscapeFilter), response);
	}

	@Override
	public void destroy() {
	}
}

 

XssEscapeServletFilterWrapperUpdate

package net.macaronics.util.filter.navercorp;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter;

import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

public class XssEscapeServletFilterWrapperUpdate extends HttpServletRequestWrapper  {
	private XssEscapeFilter xssEscapeFilter;
	private String path = null;

	public XssEscapeServletFilterWrapperUpdate(ServletRequest request, XssEscapeFilter xssEscapeFilter) {
		super((HttpServletRequest)request);
		this.xssEscapeFilter = xssEscapeFilter;

		String contextPath = ((HttpServletRequest) request).getContextPath();
		this.path = ((HttpServletRequest) request).getRequestURI().substring(contextPath.length());
	}

	@Override
	public String getParameter(String paramName) {
		String value = super.getParameter(paramName);
		return doFilter(paramName, value);
	}

	@Override
	public String[] getParameterValues(String paramName) {
		String values[] = super.getParameterValues(paramName);
		if (values == null) {
			return values;
		}
		for (int index = 0; index < values.length; index++) {
			values[index] = doFilter(paramName, values[index]);
		}
		return values;
	}

	

	@Override
	public Map<String, String[]> getParameterMap() {
		Map<String, String[]> paramMap = super.getParameterMap();
		Map<String, String[]> newFilteredParamMap = new HashMap<>();

		Set<Map.Entry<String, String[]>> entries = paramMap.entrySet();
		for (Map.Entry<String, String[]> entry : entries) {
			String paramName = entry.getKey();
			Object[] valueObj = (Object[])entry.getValue();
			String[] filteredValue = new String[valueObj.length];
			for (int index = 0; index < valueObj.length; index++) {
				filteredValue[index] = doFilter(paramName, String.valueOf(valueObj[index]));
			}
			
			newFilteredParamMap.put(entry.getKey(), filteredValue);
		}
		return newFilteredParamMap;
	}

	/**
	 * @param paramName String
	 * @param value String
	 * @return String
	 */
	private String doFilter(String paramName, String value) {
		return xssEscapeFilter.doFilter(path, paramName, value);
	}
}

 

사용

    @Bean
    FilterRegistrationBean<?> getFilterRegistrationBean() {
    	FilterRegistrationBean<XssEscapeServletFilterUpdate> filterRegistration = new FilterRegistrationBean<XssEscapeServletFilterUpdate>();
    	filterRegistration.setFilter(new XssEscapeServletFilterUpdate());
    	filterRegistration.setOrder(1);
        // registrationBean.addUrlPatterns("*.do", "*.go"); //filter¸¦ 
        // registrationBean.addUrlPatterns("*.do", "*.go" ,"/member/*"); 
        // url patterns
    	filterRegistration.addUrlPatterns("/comment/*", "/customerSupport/*"); // filter¸¦
        return filterRegistration;
    }

 

 

 

 

 

 

 

7단계 :

 jsp 오류 잡기

 

 

 

- Servlet

우선 Servlet의 패키지가 변경되었습니다.

 

javax.servlet     =====>    jakarta.servlet

 

SpringBoot 버전업을 원하시는 분들은 해당 사항 주의하시길 바랍니다.

 

- JSP, JSTL

물론, 추세에 따르면 JSP보다는 Vue.js, react 등 별도의 프론트 프레임워크 혹은 라이브러리를

 

이용하고 있지만, 혹시나 모를 JSP 이용자분들을 위해 세팅법을 알려드립니다.

 

기존 SpringBoot 2.x 와는 또 다른 부분들이 있더군요.

 

기존의 제공되는 내장형 tomcat의 의존성을 주석처리 및 제거해주도록 합니다.

[pom.xml]

<!--<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency> -->

 

이후, JSP로 View를 리턴해줄 수 있는 tomcat의 의존성을 주입해주도록 합니다.

[pom.xml]

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

 

이제 JSP 에 대한 resolver를 세팅해줄건데요, bean이 아닌 properties 를 통해 세팅해주도록 하겠습니다.

 

[application.properties]

spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp

 

위와같이 본인의 환경에 맞게 세팅을 해주시면 간단하게 완료입니다.

 

이제 JSTL 사용에 대해 알아볼건데요.

 

기존 2.x 에서 사용하듯 의존성을 주입하고 jstl을 사용하려고 하면

 

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 

JSP내에서 해당 taglib을 못받아오는 에러를 경험해보실 수 있습니다.

 

글의 상단에서 말씀 드렸듯, servlet의 패키지가 변경되었듯 jstl 또한 변경이 있었더군요.

 

그럴땐 아래의 의존성을 주입해주도록 합니다.

 

<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
    <scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>jakarta.servlet.jsp.jstl</artifactId>
    <version>3.0.1</version>
</dependency>

 

 

 

출처 :  [SpringBoot] SpringBoot 3.0 에서 Jsp, Jstl 세팅 그리고 Servlet 변경점

 

 

 

 

 

 

 

8 단계 :

 기존 프로젝트에서  추가 안한 라이브러리들을  하나씩 추가해보면서 오류를 잡아 본다.

 

 

 

 

 

 

 

 

 

 

9. 만약 JPA  프로젝트라만  Query DSL 설정 참조.

 

기존

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>5.0.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>5.0.0</version>
</dependency>

 

= > 업데이트

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>5.0.0</version>
    <classifier>jakarta</classifier>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>5.0.0</version>
    <classifier>jakarta</classifier>
</dependency>

 

오류 참조

https://github.com/querydsl/querydsl/issues/3431#issuecomment-1328623180

 

 

 

 

 

 

10. 기타   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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.5</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>net.macaronics</groupId>
	<artifactId>macaronics</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>system</name>
	<description>Macaronics system</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mustache</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-oauth2-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.mariadb.jdbc</groupId>
			<artifactId>mariadb-java-client</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<!--	
		https://islet4you.tistory.com/entry/SpringBoot-SpringBoot-30-에서-Jsp-Jstl-세팅-그리고-Servlet-변경점
		[SpringBoot] SpringBoot 3.0 에서 Jsp, Jstl 세팅 그리고 Servlet 변경점
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>-->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
			<scope>provided</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
			<version>3.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!--여기부터 커스텀 라이브러리 추가-->
		<dependency>
			<groupId>org.apache.tika</groupId>
			<artifactId>tika-core</artifactId>
			<version>2.7.0</version>
		</dependency>
		<dependency>
			<groupId>org.imgscalr</groupId>
			<artifactId>imgscalr-lib</artifactId>
			<version>4.2</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.11.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>5.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>5.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-text</artifactId>
			<version>1.10.0</version>
		</dependency>
		<dependency>
			<groupId>com.navercorp.lucy</groupId>
			<artifactId>lucy-xss-servlet</artifactId>
			<version>2.0.1</version>
		</dependency>
		<!--// After Spring Boot 3.0-->
		<dependency>
			<groupId>jakarta.xml.bind</groupId>
			<artifactId>jakarta.xml.bind-api</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>jakarta.mail</groupId>
			<artifactId>jakarta.mail-api</artifactId>
			<version>2.1.0</version>
		</dependency>
		<!--3.0 업데이트 설명서-->
		<!--		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-properties-migrator</artifactId>
			<scope>runtime</scope>
		</dependency>
		-->
		<!-- log4jdbc-remix , mybatis 쿼리 실행 보기 -->
		<dependency>
			<groupId>org.lazyluke</groupId>
			<artifactId>log4jdbc-remix</artifactId>
			<version>0.2.7</version>
		</dependency>
	</dependencies>
	<!--	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>-->
	<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.2</version>
				<configuration>
					<skipTests>true</skipTests>
				</configuration>
			</plugin>
		</plugins>
		<defaultGoal>install</defaultGoal>
	</build>
</project>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

발에 차꼬가 채워져서 걸어가지 못한다. 스스로 반성과 경계하면 허물은 없어지고 화가 전하여 복을 얻을 수도 있다. -역경

댓글 ( 4)

댓글 남기기

작성