SiteMesh와 Freemarker

Language/JSP 2012. 11. 2. 16:30

SiteMesh와 Freemarker

SiteMesh개념

-많은 페이지로 구성되는 대형 사이트를 구축할때 웹 페이지 레이아웃을 쉽게 구성하기위한 프레임워크이다.
-SiteMesh는 web-page layout이고, decoration(장식) 프레임웍이고, 일관된 look/fee, navagation, layout scheme를 필요로하는 많은 페이지로 구성된 큰 사이트를 만드는것을 도와주는 web-application 통합 프레임웍이다.
-Servlet Filter 이다. 그러므로, Servlet 2.3스펙을 따른 컨테이너가 필요하다. 
-순수자바로 구현되어있기 때문에 플랫폼에 독립적이다.

  • JRE 1.3보다 높은 버전이 요구된다. 좋은 성능을 위해 JRE 1.4.x 또는 보다 높은 버전을 사용해라.
    -Java SDK 1.4 또는 그 이상, Jakarta Ant version 1.5 또는 그이상에서 빌드해라.
    참고 : http://www.opensymphony.com/sitemesh/requirements.html/

웹서버에 요구된 정적/동적요청(request)를 가로채고, 
요청된 페이지 자원을 파싱하며 설정된 프로퍼티와 랜더링할 데이터를 컨덴츠로부터 읽어 들인 후원래의 페이지에 장식과 수정을 가하여 최종 페이지를 생성한다. 
디자인 패턴을 기반으로 만들어진 프레임워크이다.

SiteMesh 동작방식

SiteMesh 설치

  • SiteMesh 는 Filter 형태로 작용한다.
    이를 위해서 web.xml 에 다음과 같은 내용을 추가해야 한다.
    <!-- sitemesh  -->
     <filter>
            <filter-name>sitemesh</filter-name>
      <!--JSP를 위한 필터-->
            <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
     </filter>
      <!--velocity를 위한 필터 
      <filter-class>
          org.apache.struts2.sitemesh.VelocityPageFilter
      </filter-class>
      Freemarker를 위한필터
      <filter-class>
          org.apache.struts2.sitemesh.FreeMarkerPageFilter
      </filter-class>
      -->
     <filter-mapping>
            <filter-name>sitemesh</filter-name>
            <url-pattern>/*</url-pattern>
     </filter-mapping>

    *sitemesh.xml 파일설정
    decorators.xml경로와 이름을 정의한다.

  • decorators.xml 파일설정
    WEB-INF 에 decorators.xml 라는 이름의 파일을 만들고 다음 내용을 입력한다.
    애플리케이션의 각모듈 화면구성
    데코레이터가 적용될 url패턴
    데코레이터 페이지의 경로
    데코레이터를 적용하지 않을 url패턴
<?xml version="1.0" encoding="ISO-8859-1"?>

<decorators defaultdir="/chapter10/sitemesh/decorators">
    <!-- Any urls that are excluded will never be decorated by Sitemesh -->
    <excludes>
        <pattern>/debug.jsp</pattern>
        <pattern>/style/*</pattern>
        <pattern>/script/*</pattern>
        <pattern>/img/*</pattern>
        <pattern>/dojo/*</pattern>
        <pattern>/struts/*</pattern>
        <pattern>/exclude.jsp</pattern>
        <pattern>/exclude/*</pattern>
    </excludes>

    <decorator name="layout" page="layout.jsp">
        <pattern>/sitemesh*</pattern>
    </decorator>
    
    <decorator name="panel" page="layoutPanel.jsp"/>
    <decorator name="header" page="layoutHeader.jsp"/>
    <decorator name="footer" page="layoutFooter.jsp"/>    
</decorators>

*장식자 태그,페이지 태그

장식자 태그,페이지 태그장식자 페이지를 생성할 때 사용되는 태그
<decorator:head/>장식될 페이지의 <head>태그의 내용을 삽입
<decorator:body/>장식될 페이지의 <body>태그의 내용을 삽입
<decorator:title/>장식될 페이지의 <title>태그의 내용을 삽입
<decorator:getProperty/>장식이 완료된 HTML 페이지의 <body>태그 내에 이벤트 핸들러를 생성하기 위해 사용
<decorator:usePage/>장식자 페이지에서 장실될 페이지의 페이지 객체를 얻을 수 있게 함

*페이지 태그

페이지 태그장실자 페이지 내에서 다른 장식자를 포함할 때 사용
<page:applyDecorator/>현재 장식자 페이지 내에 장식될 페이지와 장식잘ㄹ 지정하여 삽입한다.
<page:param/><page:applyDecorator/> 사용시 해당 장식자에세 파라미터를 전달하기 위해 사용

FreeMarker 개념

공식 배포 사이트에서는 다음과 같이 FreeMarker를 정의하고 있다. 
"FreeMarker는 템플릿 엔진이며 템플릿을 사용하여 (어떠한 포맷이라도)텍스트를 출력하는 역할을 담당합니다. 자바 클래스 형태로 패키지로 묶어 배포하고 있으며 개발자를 위한 도구입니다"
다음 그림처럼 자바 객체에서 데이터를 생성해서 템플릿에 넣어주면, FreeMarker에서 템플릿에 맞게 변환하여 최종적으로 HTML 파일을 생성한다. 다른 언어 사용의 가능성을 배제하고 있지는 않지만, JVM에서 돌아가는 엔진이므로 주로 자바에서 사용되고 있다.

FreeMarker는 HTML 출력만을 위한 엔진은 아니고 텍스트라면 그 어떠한 것도 가능하다. 이는 텍스트에서 텍스트로의 변환이기 때문에 너무나도 당연한 얘기이다. 그렇기에 FreeMarker는 웹기반 프레임워크가 아니고 완전한 POJO기반 템플릿 엔진이다.

FreeMarker 설정

1. http://prdownloads.sourceforge.net/freemarker/freemarker-2.3.1pre.tar.gz 에서 파일 다운 
2.압축을 푼 후 freemarker.jar 파일을 WEB-INF/lib 폴더에 복사 
(예제)
template.html

<html>
<head><title>FreeMarker Test Program</title>
</head>
<body>
        ${name} 님의 방문을 환영 합니다~ <br>
        주 소 : ${info.address} <br>
</body>
</html>

template.jsp

<%@ page import = "java.util.*" pageEncoding="euc-kr" %>
<%@ page import = "java.io.*" %>
<%@ page import = "java.servlet.*" %>
<%@ page import = "java.servlet.http.*" %>
<%@ page import = "freemarker.template.*" %>

<%
        Configuration cfg = Configuration.getDefaultConfiguration();

        //현재 폴더에서 template file 로딩 하겠다는 의미
        cfg.setServletContextForTemplateLoading(getServletContext(), ".");

        //Template File Loading
        Template temp = cfg.getTemplate("template.html");

        //Create Data Model
        Map root = new HashMap();
        root.put("name","jclee");

        //계층 구조를 표시 하기 위해 HashMap에 HashMap을 추가
        //즉 템플릿에서 info.address 표시 가능
        Map info = new HashMap();
        root.put("info", info);
        info.put("address","서울 역삼동");

        //get OutStream
        Writer fout = new BufferedWriter(
                            new OutputStreamWriter(response.getOutputStream(), 
                                                temp.getEncoding()));

        //response.setContentType("text/html; charset=euc-kr");

        try {
            //Template File과 Data Model의 결합
                temp.process(root, fout);
        }
        catch(TemplateException e) {
                throw new ServletException("Error... freemarker processor");
        }

%>

freemarker문법

1. @macro

  • 프리마커 템플릿 전역에서 공통으로 사용되는 UI 디펜던트한 함수는 매크로로 만들어 여러 ftl에서 사용할 수 있도록 해준다.
  • 형식 : <@매크로명 변수1, 변수2, ... />
    - 샘플1) 긴 문자열을 적당한 크기로 자르는 기능의 매크로
       *사용법 : <@trimX ${item.title}, 20 />
       *매크로 : 
    
       <#macro trimX src max><#compress>
       <#if src?length &gt; max>
          ${src[0..max-1]}..
       <#else>
          ${src}
        </#if>
       </#compress></#macro>
     - 샘플2) YYYYMMDD 형식의 문자열을 YYYY.MM.DD 형식으로 변환하는 매크로
       *사용법 : <@parseDay ${item.regdate} />
       *매크로 : 
    
       <#macro parseDay src><#compress>
       <#if src?length == 8>
            ${src[0..3]}.${src[4..5]?number}.${src[6..7]?number}
       <#else>
          ${src}
        </#if>
       </#compress></#macro>

    2. #list

  • 배열 형식의 오브젝트를 루핑 처리할때 사용하는 프리마커 지시자이다. "로컬엘리어스_index" 라는 변수는 0부터 시작하는 시퀀스번호이다.
  • 형식 : <#list 배열객체 as 로컬엘리어스명></#list>
    - 샘플1)
    
       <#list LIST as item>
          번호 : ${item_index+1} | 이름 : ${item.name} | 아이디 : ${item.id}
       </#list>

    3. #if

  • 프리마커 조건문에 사용되는 지시자이다.
  • 형식 : <#if 조건식></#if>
    - 샘플1) string 비교
    
       <#if ENTITY.usergrade == "A" >......</#if>
    
     - 샘플2) number 비교
    
       <#if ENTITY.userclass?number == 3>.....</#if>
    
     - 샘플3) boolean 비교
    
       <#if ENTITY.isAuth()>.....</#if>

    4. #break

  • Loop문을 중단하고 다음 스크립트로 넘어가려고 할때 사용되는 지시자이다.
  • 형식 : <#break>
    - 샘플1) 루프문을 실행하는 중 5번째에서 escape 하는 예
    
     <#list LIST as item>
      <#if item_index &gt; 3><#break></#if>
     </#list>

    5. #assign

  • 프리마커내에서 사용자 정의 로컬변수가 필요할 때 사용하는 지시자이다.
  • 형식 : <#assign 로컬변수명 = 초기화값>
    - 샘플1) 
    
    <#assign CHECK = item_index>

    6. [x...y]

  • 문자열의 일정 범위를 자를때 사용하는 함수
  • 형식 : $
    Unknown macro: {문자열[1..5]}
    - 샘플1)
    
     ${item.name[1..5]}

    7. ?has_content

  • 리스트형 오브젝트가 null이 아니고 최소 1개 이상의 컨텐츠를 가지고 있는지 체크하는함수로써 ?has_content는 ?exists와 ?size>0 두가지 체크를 동시에 해주는 함수이다.
  • 형식 : 리스트오브젝트?has_content
    - 샘플1) 
    
    <#if LIST?has_content>.....</#if>

    8. ?exists

  • NULL체크 함수. if_exists는 <#if 지시자 없이도 사용할 수 있게 해주는 표현식이다.
  • 형식 : 오브젝트?exists
    - 샘플1) 
    
    <#if ENTITY.username?exists>${ENTITY.username?substring(0, 5)}</#if>
    
     - 샘플2) 
    
    <#if LIST?exists && LIST?size &gt; 0>.....</#if>
    
     - 샘플3)
     ${ENTITY.username?if_exists}

    9. ?default

  • NULL값을 대체해주는 함수
  • 형식 : 오브젝트?default(디폴트값)
    - 샘플1) ${item.userclass?default("99")}
     - 샘플2) ${item.age?default(20)}

    10. ?string

  • 문자열로 형변환하는 함수
  • 형식 : 오브젝트?string
    - 샘플1) <#if item.age?string == "29">.....</#if>
     - 샘플2) ${item.regdate?string("yyyy/MM/dd HH:mm")}
     - 샘플3) 숫자를 통화표시로 나타내는 예
      <#assign MONEY = 1234567>
      ${MONEY?string(",##0")}

    11. ?number

  • 숫자로 형변환하는 함수
  • 형식 : 오브젝트?number
    - 샘플1) <#if item.userclass?number &gt; 3>.....</#if>
     - 샘플2) ${LIST_POINTS[item.gid?number].entityname?default("")}

    12. ?js_string

  • 문자열을 자바스크립트에 유효하도록 필터링해주는 함수.
    문자열내에 싱글쿼테이션(')등이 포함되어 스크립트에 오류가 나는것을 방지하기 위하여 사용되는 함수이다. 
    화면상에는 HTML 태그로 취급된다.
  • 형식 : 오브젝트?js_string
    - 샘플1) 문자열 <img src='/image/enterprise.gif'>을 js_string으로 처리했을때 소스보기를 하면 <img src=\'/image/enterprise.gif\'>으로 출력된다.
     - 샘플2) <a href="javascript:getName('${item.homeurl?js_string}');">

    13. ?html

  • 문자열을 HTML Symbolic Entity로 필터링해주는 함수. 문자열내의 HTML태그등을 깨뜨려 화면상으로 출력되도록 할때 사용하는 함수이다. 화면상에 HTML태그가 아닌 일반 문자열로 취급된다.
  • 형식 : 오브젝트?html
  • 샘플1)
    문자열 <img src='/image/enterprise.gif'>을 html로 처리하면 화면상에 <img src='/image/enterprise.gif'> 로 출력되고 소스보기를 하면 <img src='/image/enterprise.gif'>로 출력된다.

14. ?index_of

  • 특정 문자(열)가 시작되는 위치를 정수형으로 반환한다. 인덱스는 0부터 시작됨.
  • 형식 : 오브젝트?index_of(특정문자)
    - 샘플1) "abcde"?index_of("c") 는 2를 반환한다.

    15. ?replace

  • 문자열의 일부를 주어진 문자로 대체하는 함수
  • 형식 : 오브젝트?replace(찾을문자열, 대체할문자열)
    - 샘플1) ${item.content?replace(">", "&gt;")}

    16. item_has_next
    -리스트 객체의 다음 컨텐츠가 존재하는지(EOF) 체크하는 함수
    -형식 : 리스트엘리어스이름_has_next
    -샘플1) 이름과 이름사이에 , 를 찍어주되 마지막은 찍지 않는 경우의 예

    <#list LIST as item>
          ${item.name?default("")}<#if item_has_next>,</#if>
      </#list>

참고자료

이미지 출처: http://opensymphony.com/sitemesh
스트럿츠 2 프로그래밍

문서에 대하여

'Language > JSP' 카테고리의 다른 글

mybatis[SqlSession]  (0) 2012.11.07
springmvc+mybatis  (0) 2012.11.07
Core of JSP  (0) 2012.11.02
Basic of JSP  (0) 2012.11.02
ServletContext와 RequestDispatcher  (0) 2012.11.02
: