파란하늘의 지식창고
반응형

Spring은 HTML 페이지를 렌더링 하기 위해 Thymeleaf, FreeMarker, Mustache, Groovy 와 같은 Template Engine 을 지원한다.

https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.servlet.spring-mvc.template-engines

보통 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은 Accepttext/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 응답을 처리하는 요청은 producetext/mustache 로 지정되어 있으므로 MustacheViewResolver 가 처리하게 된다.

위의 예제에서 thymeleaf 응답은 /src/main/resources/templates/thymeleafRequest.html 에서, mustache 응답은 /src/main/resources/templates/mustacheRequest.mustache 에서 처리를 한다.

동일한 주소로 producetext/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에 어떻게 데이터를 내려줘야 할지, 어떻게 내려줘야 처리가 편하게 될지 하는 도메인을 구성에 대해 여러 방법을 고민할 수 있게 해 준다.

반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요