Jersey 2, FreeMarker 템플릿 엔진 적용하기

개요

MVC 구조의 Java 웹 애플리케이션 개발시 View를 구현하는 가장 일반적인 방법은 JSP(JavaServer Pages)를 기반으로 EL(Expression Language), JSTL(JavaServer Pages Standard Tag Libaray)를 사용하는 것이다. 이 것 만으로도 충분히 직관적이고 강력한 View를 구현할 수 있지만 Java EE에 종속적이라는 단점이 존재한다.(예를 들어 이메일 템플릿 같은 경우 서블릿 컨테이너를 벗어난 애플리케이션에서 JSP로 처리하려면 별도의 프리 프로세서가 필요하다.) 이에 MVC 구조에 극단적으로 최적화되어 있으면서 Java EE에 얽매이지 않아 어디서나 사용될 수 있는 FreeMarker 템플릿 엔진을 적용하는 방법을 소개하고자 한다. Jersey 2의 기본 프로젝트 생성은 이 글을, MVCJSP 적용은 이 글을 참고한다.

/pom.xml

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-mvc-freemarker</artifactId>
    <version>2.21</version>
</dependency>
  • jersey-mvc-freemarkerMVC + FreeMarker 통합 기능을 제공하는 Jersey 2의 확장 모듈이다.

/src/main/java/.../AppConfig.java

@ApplicationPath("/")
public class AppConfig extends ResourceConfig {

    public AppConfig() {

        packages(this.getClass().getPackage().getName());
        register(FreemarkerMvcFeature.class);
    }
}

/src/main/webapp/WEB-INF/web.xml

    <filter>
        <filter-name>jersey-mvc-filter</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.jsonobject.sample.AppConfig</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.servlet.filter.contextPath</param-name>
            <param-value></param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.server.mvc.templateBasePath.freemarker</param-name>
            <param-value>/WEB-INF/views</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.servlet.filter.staticContentRegex</param-name>
            <param-value>/assets/.*</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>jersey-mvc-filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  • 이전 글과 설정이 대부분 동일하다. 유일하게 다른 점은 jersey.config.server.mvc.templateBasePath.freemarker에 대한 값으로 /WEB-INF/views 경로를 명시하였다. MVC 패턴의 View로서 기능하는 FTL 파일은 모두 /src/main/webapp/WEB-INF/views 폴더에 위치한다는 의미이다.

/src/main/java/.../HelloResource.java

@Path("/")
public class HelloResource {

    @GET
    @Path("helloworld")
    @Produces(MediaType.TEXT_HTML)
    public Viewable helloWorld() {

        Map<String, Object> model = new HashMap<String, Object>();
        model.put("title", "Jersey FreeMarker Hello World Example");
        model.put("body", "<Hello, World!>");
        model.put("footer", "This is footer message!");
        return new Viewable("/helloworld.ftl", model);
    }
}
  • 이전 글의 JSP 설정과 동일하다. 차이점은 View 기능을 하는 템플릿 파일의 확장자가 FTL이라는 것 뿐이다.

/src/main/webapp/WEB-INF/views/footer.ftl

<h3>${footer}</h3>

/src/main/webapp/WEB-INF/views/helloworld.ftl

<!DOCTYPE html>
<html>
<head>
  <title>${title}</title>
</head>
<body>
  <h2><#if body??>${body?upper_case?html}</#if></h2>
  <#include "footer.ftl">
</body>
</html>
  • FreeMarker 템플릿은 JSP + EL + JSTL 조합과 상당히 유사하면서 훨씬 간결한 느낌을 준다. 무엇보다 Jave EE를 벗어난 어떠한 Java 애플리케이션에서도 사용할 수 있다는 장점이 있다.
  • 앞서 Resource 클래스에서 전달 받은 Model 오브젝트에 담긴 데이터들은 위와 같이 바로 사용될 수 있다.
  • 변수명 뒤에 붙은 ?upper_case는 대문자로 출력하겠다는 의미이다. 뒤 이어 붙은 ?htmlHTML Escaping을 의미한다. HTML 태그와 충돌을 유발하는 모든 문자는 특수 기호로 대체되어 출력된다.
  • <#if {OBJECT_NAME}??>...</#if>는 해당 오브젝트가 Null이 아닐 경우에만 안의 내용을 출력한다는 의미이다.
  • <#include {FILE_NAME}>은 다른 템플릿 파일을 포함한다는 의미이다.

보너스, Eclipse 플러그인 설치하기

기본적인 Eclipse EE 상태에서는 FreeMarker 템플릿을 담은 FTL 파일을 인식하지 못한다. 아래와 같은 순서로 FreeMarker 플러그인을 설치할 수 있다.(Eclipse EE Mars 버전 기준으로 URL은 추후 변경될 수 있다.)

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고