본문 바로가기
Spring

SpringBoot VersionUp 전환 대응기 - thymeleaf편

by Jop 2025. 2. 14.
반응형

🌸개요🌸

SpringBoot version up (1.3.X -> 3.2.1) 과정에서 migration하는 중 타임리프 역시 2 -> 3 버전으로 올라가는 상황이였습니다.이때 thymeleaf에서 #httpServletRequest 기본 기능을 더이상 지원하지 않는 것을 확인했습니다.

https://www.thymeleaf.org/doc/articles/thymeleaf31whatsnew.html

 

Thymeleaf 3.1: What’s new and how to migrate - Thymeleaf

Thymeleaf 3.1: What’s new and how to migrate Latest version is Thymeleaf 3.1.3.RELEASE.What’s newSupport for Servlet API 5.0 and the jakarta.* class namespaceThymeleaf 3.1 adds support for the new jakarta.* class namespace in the Servlet API since vers

www.thymeleaf.org

 

As explained in the “What’s new” section, expression utility objects #request, #response, #session and  #servletContext are no longer available from expressions in templates.

 

‼️문제점

기존에는 Spring Boot에서 Thymeleaf를 사용해 웹 애플리케이션을 개발하는 경우, 이전 버전에서는 #httpServletRequest를 통해 현재 요청 정보를 쉽게 가져올 수 있었습니다.

<!-- Thymeleaf 2.x에서 사용 가능 -->
<p th:text="${#httpServletRequest.requestURI}"></p>

그러나 Thymeleaf 3.x부터 #httpServletRequest가 제거되었기 때문에, 이 코드는 더 이상 동작하지 않습니다.

#httpServletRequest.requestURI의 경우 공통 html에서 사용 중이므로 #httpServletRequest가 더이상 지원되지 않는 경우면 Controller에 modelAttribute에 해당 값을 넣어줘야되는 상황이 발생했었습니다.

 

(물론 이외에도 변경사항 및 미지원 기능이 존재했지만 httpServletRequest 기능 미지원에 대한 문제점에 대한 부분만 작성하였습니다.)

🤔 고민

모든 Controller에 modelAttribute 값을 추가해주는 노가다를 하는 것이 맞을까?

이 것은 Controller가 너무 많아 노가다를 해주는 것이 바람직하지는 않다고 생각했습니다. 그래서 전역 설정해줄 수 있는 2가지 방법에 대해서 생각해봤습니다.

 

생각 1 : @ControllerAdvice 사용한 전역 설정

@ControllerAdvice
public class ControllerHandler{

	@ModelAttribute
  public void handleRequest(HttpServletRequest request, Model model) {
      String requestURI = request.getRequestURI();
      // requestURI 값 공통적으로 model에 add
      model.addAttribute("requestURI", requestURI);
  }
}

 

생각 2 : Interceptor를 활용한 전역 설정

- global Interceptor 생성

@Component
public class GlobalRequestAttributeInterceptor implements HandlerInterceptor {
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        if (modelAndView != null) {
            String requestUri = request.getRequestURI();
            modelAndView.addObject("requestUri", requestUri);
        }
    }
}

 

- interceptor 등록

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private GlobalRequestAttributeInterceptor globalRequestAttributeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(globalRequestAttributeInterceptor);
    }
}

 

🔥 결론: 어느 방법이 더 좋을까?

비교 항목 @ControllerAdvice (@ModelAttribute) Interceptor (HandlerInterceptor)
적용 대상 Spring MVC (Thymeleaf 뷰) 모든 요청 (Thymeleaf, REST API 등)
적용 범위 Model이 있는 모든 요청 postHandle 이후 ModelAndView 응답이 있는 요청
예외 처리 @ExceptionHandler에서 별도 추가 필요 예외 발생 시 호출되지 않음
데이터 처리 시점 컨트롤러 실행 전에 Model에 추가 컨트롤러 실행 후 ModelAndView에 추가
REST API 적용 가능 여부 ❌ (불가능) ✅ (가능)

 

우선 Interceptor의 경우 모든 요청(Thymeleaf + REST API)에서 사용 가능하므로 모든 요청에 대해서 처리 할 수 있었습니다. 하지만 이 경우에는 Thymeleaf에서만 처리해주면 되기 때문에 Interceptor까지는 필요하지 않다고 생각하였습니다.

Thymeleaf 위한 처리 면 @ControllerAdvice + @ModelAttribute 활용한 처리 방식이 더 옳다고 생각해 해당 방식을 적용하였습니다 🚀 

반응형

최근댓글

최근글

skin by © 2024 ttuttak