티스토리 뷰
타임리프는 스프링 부트의 기본 View 템플릿이다.
일반적으로 Controller에 view를 매핑해주는 방법으로 사용한다.
그러나 개발을 하다보면 코드 내에서 타임리프를 파싱해서 사용하고 싶을 때가 있다.
예를 들어, 스케쥴러 내에서 타임리프로 만든 페이지를 이메일로 발송한다든지 등의 용도가 있다.
그런 경우에 타임리프를 코드 내에서 받아오는 방법에 관한 것이다.
가장 단순한 형태의 타임리프 파서는 아래처럼 만들 수 있다.
(참고로 여기에 나오는 Context 객체는 org.thymeleaf.context 패키지 내의 Context 객체이다.)
public String getTemplate(SpringTemplateEngine springTemplateEngine) {
HashMap<String, Object> mergedModel = new HashMap<>();
mergedModel.put("modelTest", "I LOVE JAVA");
Context context = new Context(Locale.KOREA, mergedModel);
return springTemplateEngine.process("kimchi", context);
}
여기서 mergedModel이 Controller의 Model 객체, 혹은 ModelAndView 객체에서 삽입해주던 데이터를 대체하는 역할을 한다.
이렇게 하면 2가지 문제가 발생한다.
- application.properties에서 값을 가져올 수 없음
- session에서 값을 가져올 수 없음
1번 문제는 ApplicationContext 객체를 타임리프에서 처리하도록 수정해주면 된다.
@Component
public class ApplicationContextThymeleaf {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private SpringTemplateEngine springTemplateEngine;
@Bean(name = "applicationContextParser")
public String applicationContextThymeleaf() {
HashMap<String, Object> mergedModel = new HashMap<>();
mergedModel.put("modelTest", "I LOVE JAVA");
// applicationContext를 삽입
ThymeleafEvaluationContext thymeleafEvaluationContext = new ThymeleafEvaluationContext(applicationContext, null);
mergedModel.put(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME, thymeleafEvaluationContext);
Context context = new Context(Locale.KOREA, mergedModel);
String value = springTemplateEngine.process("kimchi", context);
return value;
}
}
자세히 보면 아래와 같이 맵에 값이 추가된 것을 볼 수 있다.
mergedModel.put(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME, thymeleafEvaluationContext);
위 값을 맵에 추가하면 스프링의 ApplicationContext를 파라미터로 받아가 application.proprties의 값을 가져갈 수 있게 된다. 이로써 1번 문제는 해결이 된다.
2번 문제는 경우가 좀 다르다.
근본적으로 session 객체가 HttpServletRequest 객체, 즉 Http 요청이 있어야 유지될 수 있다는 근본적인 한계에서 발생하는 문제이다. 상기의 기본 예제에서 사용하고 있는 Context 객체는 HttpServletReuqest와 의존성을 갖지 않고 독립적으로 사용하기 때문에, HttpServletRequest를 삽입할 수 없다.
결국 위 예제들과 다르게, RequestMapping이 되어있는 메서드에서 HttpServletRequest 객체를 가져와서 템플릿을 렌더링 해야하며, 기존의 Context 객체는 사용할 수 없다.
@Autowired
private ApplicationContext applicationContext;
@Autowired
private SpringTemplateEngine springTemplateEngine;
@ResponseBody
@GetMapping("")
public ResponseEntity getTemplate(HttpSession session, HttpServletRequest httpServerRequest, HttpServletResponse httpServletResponse) {
session.setAttribute("kimchi", "This is JAVA");
IEngineConfiguration configuration = springTemplateEngine.getConfiguration();
HashMap<String, Object> mergedModel = new HashMap<>();
mergedModel.put("modelTest", "I LOVE JAVA");
ThymeleafEvaluationContext thymeleafEvaluationContext = new ThymeleafEvaluationContext(applicationContext, null);
RequestContext requestContext = new RequestContext(httpServerRequest, httpServletResponse, httpServerRequest.getServletContext(), mergedModel);
mergedModel.put(SpringContextVariableNames.SPRING_REQUEST_CONTEXT, requestContext);
mergedModel.put(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, requestContext);
mergedModel.put(SpringContextVariableNames.THYMELEAF_REQUEST_CONTEXT, new SpringWebMvcThymeleafRequestContext(requestContext, httpServerRequest));
mergedModel.put(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME, thymeleafEvaluationContext);
WebExpressionContext expressionContext = new WebExpressionContext(configuration, httpServerRequest, httpServletResponse, httpServerRequest.getServletContext(), Locale.KOREA, mergedModel);
return ResponseEntity.ok().body(springTemplateEngine.process("kimchi", expressionContext));
}
위 예제코드는 특정 컨트롤러 코드 안에 존재하는 Get 요청을 처리하는 메서드이다.
이제 더이상 Context를 사용하지 않고, WebExpressionContext 객체를 사용하고, 해당 객체는 engine의 설정, http 요청, http 응답과 관련된 정보를 따로 받아가기 때문에 타임리프 정보를 넘겨줄 수 있다.
(mergedModel 객체에 추가한 파라미터들은 ThyemeleafView 클래스의 renderFragment 메서드의 구현체를 참고했다.)
그렇다면, session.getAttribute를 호출하는 페이지에서, session이 없는 상태에서 파싱을 해야 하면 어떻게 해야할까?
아주 간단하다. session 뒤에 ?를 붙여서 session이 null 인 경우 호출하지 않게 하면 된다.
<span th:text="${#session?.getAttribute('kimchi')}"></span><br>
'개발 > 스프링' 카테고리의 다른 글
spring boot 3.2.2 전환기(3)- Spring Security 변경 (0) | 2024.03.25 |
---|---|
spring boot 3.2.2 전환기(2) - Spring Web MVC 변경 (0) | 2024.03.23 |
Spring boot 3.2.2 전환기(1) - 버전 변경 (1) | 2024.03.23 |
spring jpa - pessimistic write lock (0) | 2022.02.22 |
톰캣 url rewrite로 호스트헤더 고치기 (0) | 2021.06.16 |
- Total
- Today
- Yesterday
- springboot
- 토스페이
- 공익제보단
- Spring
- 홈택스
- 탈세
- 이륜차
- 한국교통안전공단
- 알리익스프레스
- 현금영수증
- k베뉴
- Thymeleaf
- JPA
- 광군제
- Request
- Java17
- ORM
- 포상금
- java
- tomcat
- Azure
- 티스토리챌린지
- 알리
- 안전신문고
- n+1
- 오블완
- 전세사기
- 부가가치세
- ouath2
- springboot3
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |