배경
사내 플랫폼 스프링 프레임워크 (레거시) 를 4에서 6로 업그레이드 하기로 결정했다.
회사 관련 불필요한 스토리는 접어둔다. 굳이 읽을 필요는 없지만 궁굼한 사람은 [더보기]를 클릭
VPN을 통해서만 접근하는 플랫폼이라는 점에서 굳이 보안을 아예 생각하지 않으려고 한건 아니다.
일이 많아서 못했다는건 그저 변명일 뿐, 뒤늦게라도 반성하고 반영하기로 결정했다.
구닥다리 디자인인 탓에 잘 아는 지인(타 회사 디자인 팀장)을 통해 디자인 외주를 요청하기로 이야기를 나눈 상태.
해당 부분은 이미 회사와도 이야기를 마친 상태인줄 알았는데, 막상 진행하고자 하니 회사에서 갑작스럽게 잠시 결정을 보류한 상황이 발생했다.
혹여나 지인쪽에서 진행이 불가능할 가능성이 있을 가능성이 있기에 우선 기획, 기능위주의 설계, 요구사항정의 우선 진행한 상태.
다자인과 프론트엔드는 이후 일이기에 우선 요구사항을 베이스로 백엔드 코드 먼저 개선작업에 들어가기로 했다.
기존 레거시 시스템은 JSP 를 사용하고 있고 이번 기회에 React라이브러리 기반 프레임워크인 Next.js 13으로 프론트영역은 분리할 예정이지만, 우선 단순하게 스프링 4에서 6으로 전환하여 기존 기능이 잘 동작하는지 확인부터 해보기로 결정했다.
스프링 버전 마이그레이션 시작!!!!
헉.. 이슈가 발생했다.. 기존 뷰 페이지 조립방식을 Tiles를 활용하고 있었는데..... 이게 지원이 안됨을 확인했다.
사실 지원안하는건 알고 있었지만, 해보면 되지 않을까해서 해봤다...
스프링 5.7인가 까지 지원된거로 아는데, 스프링 6 부터는 java servlet 패키지가 javax에서 jakarta 쪽으로 전부 변경되어 (java ee 패키지 변경) 해당 기반인 Tiles를 놓아주여야 하는 상황.
진행할때 밑단부터 새로 시작하는 프로젝트라면 그냥 postman으로 확인하거나 swagger 를 통해 api명세를 확인하며 진행하면 프론트팀과 백엔드팀의 수고를 덜 수 있었겠지만, 애초 큰 회사가 아닌 탓에 우리 단일 개발팀은 그냥 전부 해야하는 상황이고, 더불어 그동안 쌓인 불필요한 레거시 코드를 제거해야하는 미션도 있다보니 우선 기존 동작이 되는걸 확인하는게 중요했다.
추후에도 thymeleaf로 제공해야하는 이유도 있었고 다행히 jsp 파일에 el/jstl이 거의 쓰이지 않고 페이지수도 그렇게 많지 않아 thymeleaf로 바꾸는덴 크게 문제가 없는 상황이기에 가능한 결정
진행
Apache Tiles는 2017년 11월을 마지막으로 더 이상 업데이트가 진행되지 않는 종료된 프로젝트로 지금은 국비지원 학원에서도 아마 안가르치지는 않을까 싶다.
2014년,2015년쯤 당시 국비지원 학원들 사이에서는 주로 스프링3에 Apache Tiles, JSP, Oracle Database가 기본 교육 과정이였던걸로 알고 있다.
우선 기존에 있던 tiles 관련코드를 다 제거했다.
maven 기반이라 pom.xml 에 있는 tiles 디펜던시를 제거 했고, java 쪽에서 확인되는 코드는 전부 제거했다.
레이아웃 템플릿을 확인하기 위한 tiles.xml 설정파일만 남겼다.
Thymeleaf 설정시작
thymeleaf. 스프링부트가 처음 만났던 날이 기억난다.
지금과 달리 스프링부트 내장톰켓이 그닥 좋지 못했던 시절, 당시에도 주위엔 익숙한 jsp를 많이 사용하는 분위기였지만 전체적은 가장 많이 사용하는 방식은 thymeleaf 이라는 얘기와 스프링 예제도 thymeleaf 였던 기억이 어렴풋이 스친다.
그때 잠시 해보고 사이드 프로젝트로도 몇번은 해보았지만, 설정할때마다 여러 시행착오를 겪은뒤에야 성공했었는데...역시는 역시인가.
이번에도 마찬가지다.
내부적으로 기존에 쓰던 명칭을 조금씩 바뀐듯 하다.
버전이 업할때마다 당연히 그러겠지만 매번 시행착오를 겪는 것 같아 블로그하는겸 기록을 남겨본다.
01. pom.xml 에 디펜던시 추가
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring6</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>3.2.1</version>
</dependency>
기본적인 tymeleaf 는 당연하고, tiles와 같이 layout 개념으로 조립하여 쓸 예정이기에 thymeleaf-layout-dialect 또한 추가했다.
현재기준 가장 최신버전이다.
02. ThymeleafConfig 파일 생성
javaConfig 파일 하나를 만들어보자. 기존에 있던 javaConfig 를 쓸까 하다 하나의 자바파일에 여러 설정이 지저분하게 들어있는게 싫어 별도로 만든다.
아래 코드는 package 정보 이후부터의 코드이다.
import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect;
import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
@Configuration
public class ThymeleafConfig {
private final ApplicationContext applicationContext;
public ThymeleafConfig( ApplicationContext applicationContext ){
this.applicationContext = applicationContext;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
templateEngine.addDialect(new LayoutDialect(new GroupingStrategy()));
return templateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setCacheable(false);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
많은 블로그들 예제를 보면 아직도 @Autowired 를 쓰는 글이 많은데, 스프링 공식홈에서 몇년전에 생성자 주입방식을 권장한다고 이야기가 나온 뒤로부터 가능하면 생성자 주입방식을 사용하고 있다.
스프링은 다양한 의존성 주입방식을 제공하고 있는데, 추후에 이 부분에 대해서도 포스팅 할 예정이다. (내가 잊지 않으려고..)
주입방식은 둘째 치고, 우선 코드에서 가장 중요한건 아무래도 prefix 부분이랑 suffix 부분일 것이다.
Prefix 부분에 html 파일을 넣으면 된다.
# 기본
templateEngine.addDialect(new LayoutDialect());
# head merge
templateEngine.addDialect(new LayoutDialect(new GroupingStrategy()));
기본설정만 해도 되긴하는데, new GroupingStrategy() 를 생성자 파라메터로 넣어주면 fragments 조각이 합쳐질때 layout head 부분과 fragment에서 작성된 head 가 합쳐진다. 스크립트나 CSS가 합쳐져서 마치 layout head 부분으로 들어간다.
필요에 따라 설정하면 좋을 듯 싶다.
03. javaConfig (Configuration 파일) 내에 Thymeleaf 뷰 리졸버 등록
/***
본인의 프로젝트에서 관리하는 javaConfig 파일 ( implements WebMvcConfigure )에서 설정하세요.
아래는 예시입니다.
*/
@Configuration
@EnableWebMvc
@ComponentScan( ... )
@MapperScan( ... )
public class AppConfig implements WebMvcConfigurer {
// 생성자 주입 방식으로 thymeleafViewResolver 가져옴
private final ThymeleafViewResolver thymeleafViewResolver;
public AppConfig(ThymeleafViewResolver thymeleafViewResolver){
this.thymeleafViewResolver = thymeleafViewResolver;
}
...
// 뷰 리졸버 등록
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// 스프링MVC 요청의 Accept헤더가 JSON인 경우 객체를 JSON 오브젝트로 변환하여 응답처리
registry.enableContentNegotiation(new MappingJackson2JsonView());
// Thymeleaf 뷰 리졸버 등록
registry.viewResolver(thymeleafViewResolver);
}
....
}
본인들 프로젝트 설정java파일에 위와같이 뷰 리졸버를 바라볼수 있도록 설정해두면 이제 thymeleaf 설정은 끝
다음 포스팅에 html 등록 및 layout 설정등에 대해 작성할 예정이다.
'자바 > Spring Framework' 카테고리의 다른 글
lucy-xss-servlet-filter Spring 6 용 JAR 빌드/적용 (2) (0) | 2023.08.17 |
---|---|
lucy-xss-servlet-filter Spring 6 용 JAR 빌드/적용 (1) (2) | 2023.08.17 |
lucy-xss-servlet-filter Spring 6 (jakarta servlet)에서 사용 (0) | 2023.08.11 |
스프링 프레임워크 6 thymeleaf Layout 설정 (0) | 2023.05.11 |