JSP/Freemarker 템플릿 상속을 통한 레이아웃 관리 프로그래밍

ᅟJava 웹 개발자들은 웹 페이지 템플릿 프레임워크는 JSP나 Freemarker 등을 사용하고 레이아웃을 관리할 때는 또 SitemeshTiles 같은 별도 프레임워크를 도입하고 있다. 사실 얼마전까지는 다른 선택사항이 없었다.

하지만 Java 외의 다른 언어 세계에서는 레이아웃을 관리할 때 별도의 프레임워크를 거의 사용하지 않고 있다. Django, Jade, Jinja2 같은 템플릿 프레임워크들을 보면 템플릿 상속(template inheritance)이라는 개념을 통해 레이아웃을 굉장히 쉽고 간편하게 관리한다.

템플릿 상속은 객체 지향 언어에서 클래스 상속과 약간 비슷하다. 부모 클래스에서 뼈대를 만들어 놓으면, 자식 클래스에서 일부 메소드를 재정의 하여 부모의 뼈대는 재활용 하면서 일부 기능을 바꿔치기 하듯, 템플릿 상속도 부모 템플릿에 레이아웃의 기본 뼈대를 만들고, 자식 템플릿에서 부모 템플릿의 특정 영역을 바꿔치기 하는 방식으로 레이아웃을 관리한다. 사실 이 형태는 이미 Sitemesh에서 다소 불편한 방식으로 유사하게 작동하고 있다.

템플릿을 상속할 때 좋은 점은 별도의 프레임워크가 필요없고, 그에 따른 설정도 필요없다. Java에서 클래스 상속하려고 별도 XML 설정 파일 만들어서 관계를 기술하거나 하지는 않지 않는가? 단지 자식클래스 extends 부모클래스라고 자식 클래스에 기술할 뿐이다.

템플릿 상속을 일단 알게 되면 그 뒤 부터는 별도 프레임워크(Sitemesh, Tiles 등)을 사용한 레이아웃 관리는 정말 정말 귀찮은 일이 되어버린다. 그런데 Java 진영은 아직도 대부분 JSP를 사용하고 그 나머지 일부는 Freemarker를 사용하는 형국인지라 이게 이만저만 불편한게 아니다.

그래서 그냥 Freemarker용 템플릿 상속 지시자(directive)와 JSP용 템플릿 상속 태그 라이브러리(tag library)를 만들었다(Freemarker의 지시자는 JSP의 태그 라이브러리 같은 것).
템플릿 상속은 콜럼부스의 달걀과 비슷하게 그 아이디어를 처음 내는게 어렵지 실제 사용 방법은 정말 말도 안된다 싶을 정도로 쉽다.

JSP를 예로 보여주면 다음과 같이 하면 레이아웃이 끝난다. Java외의 다른 언어를 해본 적이 없는 사람이라면 설정이 너무 없어서 진짜? 라고 되물을지도 모른다.

Layout 역할을 하는 base.jsp
<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JSP Template Inheritance</title>
    </head>

<h1>Head</h1>
<div>
    <layout:block name="header">
        header
    </layout:block>

</div>

<h1>Contents</h1>
<div>
    <p>
    <layout:block name="contents">
        <h2>Contents will be placed under this h2</h2>
    </layout:block>

    </p>
</div>

<div class="footer">
    <hr />
    <a href="https://github.com/kwon37xi/jsp-template-inheritance">jsp template inheritance example</a>
</div>
</html>


Layout을 사용하여 실제 내용을 채워넣는 JSP 페이지
<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<layout:extends name="base.jsp">
    <layout:put name="header" type="REPLACE">
        <h2>This is an example about layout management with JSP Template Inheritance</h2>
    </layout:put>

    <layout:put name="contents">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin porta,
        augue ut ornare sagittis, diam libero facilisis augue, quis accumsan enim velit a mauris.
    </layout:put>

</layout:extends>


딱 보면, 부모 페이지의 <layout:block> 부분이 자식 페이지의 <layout:put>에 의해 대체되는 방식으로 작동한다는 것을 이해할 수 있을 것이다.
여러번에 걸친 상속도 물론 가능하기 때문에 가장 바깥 레이아웃과 그것을 상속하는 여러개의 중간 레이아웃을 만드는 것도 가능하다.

자세한 설명은 링크를 타고가서 보면 된다.

그리고 마지막으로 이제는 Java 개발자들도 JSP 좀 버렸으면 좋겠다(아래 내용 대부분은 Freemarker도 마찬가지).

  • JSP는 범용 템플릿이고, 구문도 장황해서 대부분의 템플릿 작업인 HTML에 사용하기에는 코드가 너무 지저분해진다.
  • JSP는 기본적으로 데이터를 HTML Escape하지 않기 때문에 Cross Site Scripting 공격에 취약해지는 코드를 짜기 쉽다. 기본을 HTML Escape으로 하고, 특별한 경우에 변환 없이 바로 출력하게 하는 것이 더 안전하다.
  • MVC 분리로 로직과 뷰단이 별개로 존재할 수 있는 상황에서 JSP 컨테이너에 의존적인 환경은 뷰 전용 기능(JSP에서는 Tag Library나 JSTL Function등)을 만들고 테스트하기가 어렵다.

위와 같은 이유들 때문이다.

요즘 Java 진영에도 JSP와 Freemarker 외의 대안들이 나오고 있다. 아래 소개하는 것들은 어쩌면 아직은 완전히 무르익지 않았을지 모르지만 내가 눈여겨 보고 있는 것들이다.
  • Jade4j / Spring-Jade4j : 요즘 내가 가장 눈여겨 보고 있다.
  • Trimou : 매우 많은 언어로 포팅된 Mustache 템플릿의 구현체
  • 추가 : Handlebars : 현재 사용중. Mustache를 계승하여 기능을 좀 더 보강.


덧글

  • 지나가는사람 2013/09/13 16:07 # 삭제 답글

    좋은 정보 감사합니다. mustache라는게 상당히 괜찮아 보이네요.
  • 서영아빠 2014/12/28 00:38 # 삭제 답글

    안녕하세요.

    평범한 개발자 서영아빠입니다.
    먼저 'JSP Template Inheritance' 개발에 감사합니다.

    제가 이번에 'JSP Template Inheritance'을 약간 수정하여 제 프로젝트(https://github.com/axisj-com/axu4j)에 포함하였습니다.
    AXU4J는 AXU라는 '반응형 웹 애플리케이션 템플릿 패키지'을 template/tag engine을 활용해서 재사용성과 유지보수성을 향상시킨 프로젝트 입니다.

    라이선스는 현재 LGPL2인데 아파치와 문제가 있다는 글을 봐서 조만간 재검토 후 수정하도록 하겠습니다.(http://linuxism.tistory.com/1143)

    보시고 만약 문제가 있다면 깃헙 이슈에 남겨주세요.
    문제가 없다면 Star 해주세요.^^;;
  • 권남 2014/12/28 20:17 #

    라이센스 명시만 철저히 하시고 해당 라이센스에 대한 규칙만 지키신다면 어떻게 하셔도 상관 없습니다.
  • kiuk 2016/12/22 09:19 # 삭제 답글

    좋은정보 감사합니다. Spring Web 개발환경에서 JSP를 버리고 mustache나 handlebar를 쓴다고 한다면 세션처리라던지 스프링시큐리티 처리는 어떤식을 해야될까요?
  • 권남 2016/12/22 23:43 #

    mustache는 제가 보기엔 Java 환경에서 쓰기엔 좀 무리가 있어보이고, handlebars를 추천하고요,
    세션 처리는 문제될게 없어보이고, SpringSecurity는 handlebars용 커스텀 태그를 만들어서 사용하고 있습니다.
댓글 입력 영역