'Decorator'에 해당되는 글 1건

Page Layout & Decoration with SiteMesh :: 2009/07/08 23:14

자바 웹어플리케이션에서 페이지 레이아웃 프레임워크로 주로 사용되는 것 중에는 OpenSymphony의 SiteMesh와 Apache의 Tiles가 있다. 페이지를 구성하는 방식에 차이가 있는데 SiteMesh는 Decorator 패턴을, Tiles는 Composite View 패턴을 사용한다. 이 두 방싱의 비교는 이곳에서 참조할 수 있다. 화면 레이아웃 구성이 어느정도 정형화 되어 있다면, 개별적으로 설정을 할 필요 없이 전체 어플리케이션에 Decorator를 한 번에 적용할 수 있는 SiteMesh가 나을 것이다.

SiteMesh를 이용한 페이지 레이아웃과 동적 메뉴 구성 방법을 정리해 본다.

1. 웹어플리케이션에 SiteMesh 설정하기
  - /WEB-INF/web.xml 파일에  다음과 같이 SiteMesh Filter를 설정해 준다.
<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. SiteMesh 커스텀 설정하기
  - 다음과 같은 내용의 sitemesh.xml 파일을 WEB-INF 밑에 둔다. 이 파일이 없으면 JAR 패키지내에 포함된 sitemesh-default.xml 설정파일을 사용하여 기본 decorators.xml 위치 및 기본 Parser, Mapper를 사용한다.
<sitemesh>
  <property name="decorators-file" value="/WEB-INF/decorators.xml"/>
  <excludes file="${decorators-file}"/>
   
  <page-parsers>
    <parser default="true" 
	    class="com.opensymphony.module.sitemesh.parser.FastPageParser"/>
    <parser content-type="text/html"
	    class="com.opensymphony.module.sitemesh.parser.FastPageParser"/>
  </page-parsers>

  <decorator-mappers>
    <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
      <param name="config" value="${decorators-file}"/> 
    </mapper>
  </decorator-mappers>
</sitemesh>

3. Decorator 설정하기
  - decorators.xml 파일에 SiteMesh decorator 설정 정보를 지정한다. 각 decorator를 적용시킬 페이지들에 대한 URL 패턴을 지정한다. 적용을 제외시킬 URL 패턴도 지정할 수 있다.
<decorators defaultdir="/decorators">
    <excludes>
        <pattern>/40*.jsp</pattern>
        <pattern>/includes/*</pattern>
        <pattern>/resources/*</pattern>
    </excludes>
    <!--
    <decorator name="printable" page="printable.jsp" />
    <decorator name="popup" page="popups.jsp">
        <url-pattern>/popups/*</url-pattern>
    </decorator>
    -->    
    <decorator name="default" page="default.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

4. Decorator 작성하기
  - 페이지 레이아웃을 위해 decorator를 작성한다. 아래는 Header, Menu, Content (Left + Main), Footer 구성을 가지는 화면 레이아웃 예이다.
  - SiteMesh의 decorator 태크 라이브러리를 지정한다.
  - 접근하는 최종 HTML 페이지의 <head> 태크 내용을 <decorator:head/> 부분에 삽입하고, <body> 태그의 내용을 <decorator:body/> 부분에 삽입한다. 또한 <decorator:title/>을 이용해 HTML의 <title> 값을 가져올 수 있다.
  - 자세한 SiteMesh Tag Reference는 이곳에서 참조할 수 있다.
  - Decorator의 <body>에 포함된 <decorator:getProperty property="." [default="."] [writeEntireProperty="." ]/>는 HTML의 <body> 태크 자체에 포함된 속성(id, onload 등)을 그대로 포함하기 위한 것이다.
  - <meta> 태그의 값을 가져오기 위해서 'meta.이름' 형태로 프로퍼티를 가져올 수 있다.
<%@ page language="java" errorPage="/error.jsp" pageEncoding="UTF-8"
        contentType="text/html;charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title><decorator:title/></title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link rel="stylesheet" type="text/css" media="all" 
        href="<c:url value='/styles/default.css'/>" />
  <script type="text/javascript" src="<c:url value='/scripts/global.js'/>"></script>
  <decorator:head/>
</head>
<body<decorator:getProperty property="body.id" writeEntireProperty="true"
    /><decorator:getProperty property="body.onload" writeEntireProperty="true"/>>
  <div id="page">
    <div id="header">
      <jsp:include page="/includes/header.jsp"/>
    </div>
    <div id="menu">
      <c:set var="currentMenu" scope="request"><decorator:getProperty
          property="meta.menu"/></c:set>
      <jsp:include page="/includes/menu.jsp" />
    </div>
    <div id="content">      
      <div id="left">
        <jsp:include page="/includes/left.jsp" />
      </div>
      <div id="main">
        <div id="indicator">
          <jsp:include page="/includes/indicator.jsp" />
        </div> 
        <decorator:body/>
      </div>
    </div>
    <div id="footer">
      <jsp:include page="/includes/footer.jsp"/>
    </div>
  </div>
</body>
</html>

5. 동적 메뉴 구성하기
  - HTML 페이지의 head에 다음과 같이 meta 태그를 셋팅한다.  서브 메뉴가 존재할 경우 유사한 방식으로 추가 지정할 수 있다.
<%@ page language="java" errorPage="/error.jsp" pageEncoding="UTF-8"
        contentType="text/html;charset=utf-8"%>
<%@ include file="/includes/taglibs.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Menu1 Title</title>
    <meta name="menu" content="menu1" />
</head>
<body>
    <h1>Page Title</h1>    
    <p>Main content goes here...</p>
</body>
</html>
  - Decorator에서 다음과 같이 JSTL을 사용하여 HTML 페이지에서 선언한 meta 태그 값을 변수로 정의한다.
<c:set var="currentMenu" 
        scope="request"><decorator:getProperty property="meta.menu"/></c:set>
  - Decorator에 포함할 메뉴 JSP 파일을 다음과 같이 작성한다. 해당 메뉴에 대한 meta 태크 값일 경우 해당 메뉴에 대해 현재 선택된 메뉴로 적용할 CSS 클래스가 지정되게 한다.
<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8"%>
<%@ include file="/includes/taglibs.jsp"%>
<ul>
  <li><a 
    class="<c:if test="${currentMenu == 'home'}"><c:out value="current" /></c:if>"
    href="<c:url value='/'/>">Home</a></li>
  <li><a 
    class="<c:if test="${currentMenu == 'menu1'}"><c:out value="current" /></c:if>"
    href="<c:url value='/menu1.htm'/>">Menu1</a></li>
  <li><a 
    class="<c:if test="${currentMenu == 'menu2'}"><c:out value="current" /></c:if>"
    href="<c:url value='/menu2.htm'/>">Menu2</a></li>
  <li><a 
    class="<c:if test="${currentMenu == 'menu3'}"><c:out value="current" /></c:if>"
    href="<c:url value='/menu3.htm'/>">Menu3</a></li>
</ul>
  - CSS 파일에 해당 스타일 클래스를 작성한다. 아래는 한 예시이다.
div#menu ul li a.current {
    color: #fff;
    background: #fff url("images/current-bg.gif") top left repeat-x;
    padding: 10px 15px 0;
}

6. SiteMesh를 이용하여 페이지 레이아웃과 동적 메뉴가 적용된 화면 예시
User inserted image

User inserted image

7. 라이브러리 구성
  - SiteMesh는 서블릿 필터의 구현체로 JDK 1.4 이상, 서블릿 스펙 2.3 이상의 환경에서 사용할 수 있다.
  - JSP 스펙 1.2 (서블릿 스펙 2.3)인 경우에 JSTL 1.0이 필요하며, JDK 1.4를 이용할 경우 Apache Xerces가 추가로 필요할 것이다.
  - JSP 스펙 2.0 (서블릿 스펙 2.4) 이상인 경우에는 JSTL 1.1을 사용할 수 있으며, JDK 1.5 이상인 경우 Xerces를 별도로 추가할 필요가 없다.
User inserted image