반응형

마이그레이션 참고 문서

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide

 

GitHub - spring-projects/spring-boot: Spring Boot

Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.

github.com

 

Spring boot 3.0대로 올라가며 Java 17 버전을 베이스로 동작을 한다고 합니다.

그래서 project에 사용하는 Java 8.0과 Spring boot 2.3.*의 버전을 업그레이드를 진행하게 됐습니다.

이 글은 변경을 진행하며 발견한 이슈를 정리하는 글이며,, 계속해서 업데이트해갈 예정입니다...!
 * 2.3 ~ 3.0 사이에 변경된 내용들을 정리할 예정입니다.

 

업그레이드를 하기전 왜 많은 기업에서 8.0버전을 사용하는 이유를 짧게 찾아봤다.
다른 이유들도 많겠지만 LTS(Long Term Support)라 사용해왔다는 글들을 발견했다. 

17버전 부터는 8.0버전과 지원기간이 차이가 많이 나지 않고,
Spring boot 3.0이 17버전을 베이스로하기 때문에 업데이트를 진행하게 됐다..

Spring boot Version 변경 (Gradle)

더보기

build.gradle 설정 변경

...
plugins {
    id 'org.springframework.boot' version '3.0.0' // 3.0.0으로 변경
    ...
}
...

// Java version 변경
sourceCompatibility=17
targetCompatibility=17

assert System.properties["java.specification.version"] == "17"
...

gradle 버전업
gradle-wrapper.properties 설정 변경

distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip

 

 

1. properties에러

더보기

active profile 설정 방법이 2.4 버전부터 변경됨

https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4#profile-activation

  • profiles 설정 방법: spring.profiles에서 spring.config.on-profile로 변경됨
  • include 설정 방법: spring.profiles.include에서 spring.profile.group로 설정

 

서버 실행 명령어

java -jar -Dspring.profiles.active=dev {SPRING_PROJECT}.jar
  • 기존 application-dev.yml 설정
spring:
  profiles: dev
  profiles.include:
      - swagger
  • 변경
# application.yml
spring:
  profiles:
    group:
      dev: swagger,debug
      test: swagger
---
# application-dev.yml
spring:
  config:
    activate:
      on-profile: dev
  datasource:
    ...
---
# application-test.yml
spring:
  config:
    activate:
      on-profile: test
  datasource:
    ...
---
# application-prod.yml
spring:
  config:
    activate:
      on-profile: prod
  datasource:
    ...

 

2. cannot find javaee.*

더보기

spring boot 3.0부터는 javax.*이 대신 Jakarta EE 9 API()를 사용

 

javax를 jakarta로 변경해주기만 하면 됨

// 기존
import javax.servlet.??

// 변경
import jakarta.servlet.??

 

3. spring-security-without-the-websecurityconfigureradapter WebSecurityConfigurerAdapter Deprecated

더보기
In Spring Security 5.7.0-M2 we deprecated the WebSecurityConfigurerAdapter,
as we encourage users to move towards a component-based security configuration.

Spring Security 5.7.0-M2부터 WebSecurityConfigurerAdapter을 더이상 사용할 수 없음
자세한 해결 방법은 아래 링크 참조하면 되며 간단히 수정한 내용을 작성함

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

 

1. WebSecurity config 설정 변경
WebSecurityCustomizerbean을 등록하는 것입니다.
* 5.8에서 변경된 내용 web.ignoring().antMatchers -> web.ignoring().requestMatchers

// 기존
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}

// 변경
@Bean
public WebSecurityCustomizer configure() throws Exception {
    // web.ignoring().antMatchers(HttpMethod, "")
	// -> web.ignoring().requestMatchers(HttpMethod, "")
    return (web) -> web.ignoring().requestMatchers(HttpMethod.OPTIONS, "/**");

}

2. HttpSecurity config 설정 변경  (수정필요)
SecurityFilterChainbean을 직접 등록하는 방식으로 변경
 * 5.5에서 변경된 내용 HttpSecurity.authorizeRequests() -> HttpSecurity.authorizeHttpRequests()

// 기존
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
         // .antMatchers(ApiConstants.SAMPLE).hasAnyAuthority(AuthEnum.ADMIN.getName)
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
}

// 변경
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
         // .requestMatchers(ApiConstants.SAMPLE).hasAnyAuthority(AuthEnum.ADMIN.getName)
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
    return http.build();
}

 

3. UrlAuthorizationConfigurer.AuthorizedUrl.access -> AuthorizeHttpRequestsConfigurer.AuthorizedUrl.access
attribute 문자열을 통해 권한을 부여하는 방식이 변경됨
access(String attribute) -> access(AuthorizationManager<RequestAuthorizationContext> manager)

API별 권한 부여방식이 변경됨
antMatchers -> requestMatchers

// 기존
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        ...
        .authorizeRequests()
        	.antMatchers("/api/v1").access("permitAll()")
        ...
 }
// 변경
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        ...
        .authorizeHttpRequests((authorize) ->
			authorize.requestMatchers("/api/v1")
				.access(new WebExpressionAuthorizationManager("permitAll()"))
        ...
	return http.build();
 }

 

4. Jasypt 오류 - auto configuration 설정방식 변경

더보기

properties 암호화로 사용하던 Jasypt가 동작을 안하는 오류가 발생했다..

 

원인은 3.0버전부터 auto-configuration 설정파일의 형식이 변경됐기 때문
기존: META-INF/spring.factories에 원하는 configuration 정의
변경: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports에 정의

3.0에서 변경된 auto-configuration 등록 방법에 대응하기 위해선 라이브러리에 변경사항이 반영돼야 함

다음 이슈를 참고해 강제로 auto-configuration을 등록해 해결함
- https://github.com/ulisesbocchio/jasypt-spring-boot/issues/342

@ImportAutoConfiguration(classes = JasyptSpringBootAutoConfiguration.class) // Remove when Jasypt is released for spring boot 3 (or at least 2.7)
@SpringBootApplication
public class SampleApplication {
    ...
}

 

 

5. swagger-ui 404

더보기

Spring boot 3.0으로 마이그레이션하니 swagger-ui가 동작하지 않게됨
springfox git을 가보니 나만 그런게 아니라 안심이 됐다(?)

 

https://springdoc.org/

springdoc 공식 사이트에선 springdoc-openapi v2를 사용하면 3.0에서 사용 가능하다고하니
갈아탈 준비를 해야겠다..
우선 swagger-ui를 사용한 API doc 수정은 우선순위를 미루기로 결정


반응형
반응형


SPA를 사용하다보면 발생하는 새로고침 에러..
SPA는 모든 주소가 index.html을 향하게 돼있어 주소를 입력해 접속하거나, 새로고침을 하게되면
아래 첨부한 사진과 같이 404에러가 발생하게된다.

새로고침을 해도 해당 페이지로 이동을 하고싶다면 어떻게 해야될까?
방법은 간단하다. 앞서 말한 SPA의 특징인 모든 주소가 index.html을 향하게 된다는것을 이용하면 된다.
404 페이지는 error 페이지다. error가 발생하게 되면 index.html로 이동해주는 Controller를 만들면된다.
spring boot의 내장 인터페이스인 ErrorController를 상속해 에러발생시 index.html로 이동시켜줄 controller를 구현하겠다.

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class CustomErrorController implements ErrorController {

    private final String ERROR_PATH = "/error";

    @GetMapping(ERROR_PATH)
    public String redirectRoot(){
        return "index.html";
    }

    @Override
    public String getErrorPath(){
        return ERROR_PATH;
    }
}


오버라이드하는 getErrorPath의 경우 Spring 2.3.X 버전부터 사라졌다고 한다(https://stackoverflow.com/questions/62436379/how-to-replace-errorcontroller-deprecated-function-on-spring-boot)
getErrorPath를 제거하거나 하위호환을 위해 @Override 어노테이션을 제거한 후 null을 리턴하게해 사용하면 된다.

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class CustomErrorController implements ErrorController {

    private final String ERROR_PATH = "/error";

    @GetMapping(ERROR_PATH)
    public String redirectRoot(){
        return "index.html";
    }

    public String getErrorPath(){
        return null;
    }
}

반응형

+ Recent posts