Spring Boot WebMVC에서 Thymeleaf, Mustache ViewResolver 같이 사용하기
Spring은 HTML 페이지를 렌더링 하기 위해 Thymeleaf
, FreeMarker
, Mustache
, Groovy
와 같은 Template Engine
을 지원한다.
보통 Thymeleaf
를 많이 쓰지만 다른 것과 같이 사용하고 싶은 경우가 있을 수 있다.
Spring은 이를 위해 요청에 따라 Template Engine을 분기하여 처리하는 ContentNegotiatingViewResolver
를 제공한다.
설정
사용하려는 template engine 관련 지원 dependency를 다음과 같이 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
기본적으로 template engine은 Accept
가 text/html
으로 오는 요청을 처리하는데 하나는 text/html
요청을 담당하도록 하고 다른 template engine은 별도의 요청에 대해 처리하도록 설정한다.
mustache의 요청은 text/mustache
인 경우 사용하도록 설정하려면 다음과 같이 설정한다.
spring.mustache.servlet.content-type=text/mustache
참고: 이전엔 요청의 확장자(예를 들어 index.html, index.mustache 같은)를 기준으로 분기 처리를 지원하였지만 현재 해당 기능은 더 이상 지원하지 않는다.
사용
Thymeleaf/Mustache에 대한 controller에 requestMapping에 produce
를 설정하면 된다.
@Controller
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public class ThymeleafController {
@GetMapping("/thymeleafRequest")
public void method() {
// thymeleaf로 처리하는 요청
}
}
@Controller
@RequestMapping(produces = "text/mustache" )
public class MustacheController {
@GetMapping("/mustacheRequest")
public void method() {
// mustache로 처리하는 요청
}
}
mustache 응답을 처리하는 요청은 produce
가 text/mustache
로 지정되어 있으므로 MustacheViewResolver
가 처리하게 된다.
위의 예제에서 thymeleaf 응답은 /src/main/resources/templates/thymeleafRequest.html
에서, mustache 응답은 /src/main/resources/templates/mustacheRequest.mustache
에서 처리를 한다.
동일한 주소로 produce
가 text/html
인 경우와 text/mustache
에 대한 분기 처리도 가능하다.
@Controller
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public class ThymeleafController {
@GetMapping("/sameurl")
public void method() {
// thymeleaf로 처리하는 요청
}
}
@Controller
@RequestMapping(produces = "text/mustache" )
public class MustacheController {
@GetMapping("/sameurl")
public void method() {
// mustache로 처리하는 요청
}
}
위 예제의 경우 /sameurl
로 요청 시 Accept
header의 값에 따라 그 분기가 결정된다.
요청 시 header에 Accept=text/mustache
가 설정되어 있으면 MustacheController
가 처리한다.
개인적으로 htmx를 사용해 보면서 html 조각을 내려줄 때 thymeleaf가 아닌 mustache를 사용해 보면 어떨까 싶어서 여러 template engine을 사용하는 방법을 알아보았다.
javascript로 data와 template을 조합해 html에 렌더링 하는 코드를 작성하는 게 귀찮아서 별도의 javscript 작성 없이 server에서 내려주면서 바로 data와 template을 처리하는 것이 편할 것 같았다.
결론적으로 mustache를 사용하진 않을 것 같다.
다국어 처리나 날짜 포맷 처리, 권한 관련 처리 같은 것들을 Logic-less template인 Mustache에서 사용하기엔 불편한 점이 많았다.
다만 logic-less template에 어떻게 데이터를 내려줘야 할지, 어떻게 내려줘야 처리가 편하게 될지 하는 도메인을 구성에 대해 여러 방법을 고민할 수 있게 해 준다.