어제 포스트에 이어서..이제는 사이트매쉬를 한번 사용해보자.

사이트매쉬는..레이아웃 템플릿을 만들어놓고

사용한다. 마치 상단,좌측 메뉴등을 인클루드로 만들어 놓고 사용 하듯이..

사이트매쉬를 사용하면 굳이 include를 사용하지 않더라도 자동으로 정해진 레이아웃으로

화면이 출력된다.

filter를 적용하여 사용자가 날린 request를 가로채서 선작업을 하는 것 같다.


일단, 사용하기 위해서는 jar를 받아야 한다. sitemesh-2.3.jar

전체 소스를 받으면 샘플도 들어있다..

www.opensymphony.com/sitemesh/

그리고 이제 설정을 시작하자..일단 filter를 적용하기 위해 web.xml을 손본다.

 <!-- sitemesh -->
 <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>
 <!-- // sitemesh -->


우선은 모든 url에 대해서 적용이 되도록 하였다.


그다음에는 몇가지 설정 파일을 만들어야 하는데 sitemesh.xml과 decorators.xml 이다.

WEB-INF 밑에 만들어서 넣어두자.


sitemesh.xml

<?xml version="1.0" encoding="UTF-8"?>
<sitemesh>
    <property name="decorators-file" value="/WEB-INF/decorators.xml" />
    <excludes file="${decorators-file}" />

    <page-parsers>
        <parser content-type="text/html"
            class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
        <parser content-type="text/html;charset=UTF-8"
            class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
    </page-parsers>

    <decorator-mappers>
  <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper">
   <param name="decorator" value="printable" />
   <param name="parameter.name" value="printable" />
   <param name="parameter.value" value="true" />
  </mapper>

  <mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper" >
   <param name="property" value="meta.decorator" />
  </mapper>

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




decorators.xml

<?xml version="1.0" encoding="UTF-8"?>
<decorators defaultdir="/decorator">
    <decorator name="main" page="main.jsp">
          <pattern>*</pattern>
    </decorator>

    <decorator name="panel" page="panel.jsp"/>
</decorators>




sitemesh.xml은 사이트매쉬 자체에 대한 설정 파일이다.

어떤 decorator를 사용할지 mapper를 결정하고
parser를 설정한다.

예를 들면, 위의 경우
<property name="decorators-file" value="/WEB-INF/decorators.xml" />
로 설정 파일을 정하고
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
            <param name="config" value="${decorators-file}" />
</mapper>

이 mapper에 의해서 저 설정 파일을 사용하여 decorator를 정한다.

그리고 
    <page-parsers>
        <parser content-type="text/html"
            class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
        <parser content-type="text/html;charset=UTF-8"
            class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
    </page-parsers>

이 설정으로 해당 페이지의 content-type이 뭐라고 쓰여있는지에 따라서
데코레이터가 결정된다.

매칭되는게 없으면 적용이 안되는듯하다.. (실제 해보니까 그렇다..)

그외 여러 설정은 http://kkaok.tistory.com/search/sitemesh 여기 참조..

http://wiki.javajigi.net/display/OSS/SiteMesh 여기도 참조..

decorators.xml은 실제로 어떤 파일이 데코레이터가 되는지 결정한다.

위 설정에서는 기본적으로 main.jsp가 되고 그외 panel이라는 이름으로

추가적인 데코레이터를 설정해 두었다.

main.jsp와 panel.jsp를 보면..

main.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%>
<html>
<head>
<title><decorator:title default="main"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">

</style>
<decorator:head />
</head>
<page:applyDecorator page="/panelCounter.jsp" name="panel" />
<body>
<decorator:body />
</body>
</html>




 

panel.jsp


<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>

<p>
 <table width=250 border=0 cellpadding=0 cellspacing=0>
  <tr>
   <th class="panelTitle">
    <decorator:title default="Unknown panel" />
   </th>
  </tr>
  <tr>
   <td class="panelBody">
    <decorator:body />
   </td>
  </tr>
 </table>
</p>



템플릿이 작성되어있다.

실제 화면에 보여질 (결과 값을 가지고 있는) 페이지의 내용이 위에서 정의한 main.jsp 안에 들어가게 된다.

<decorator:title default="title defualt"/>
<decorator:head />
<decorator:body />

에 의해서 각 태그에 해당되는 값들이 저 안에 속속 들어가게 되는 것이다.

그리고

<page:applyDecorator page="/panelCounter.jsp" name="panel" />

이것은 main.jsp 안에서 다른 파일을 불러와서 데코레이터를 적용해 보여주고 있는데
panelCounter.jsp란 파일에 panel이라는 이름으로 decorators.xml에 설정되어있는 데코레이터 파일을 적용해서
main.jsp와 같이 보여주겠다는 뜻이다.

그외 여러가지 사용법이 있는데 위 링크를 참조하면 될 듯하다.

이렇게 해놓으면.. 앞에서 viewresolver를 프리마커로 설정해놨기 때문에

예를 들면

main.gs 를 호출 하면 해당 컨트롤러에서 welcome 이라는 이름의 뷰를 호출 하고 이는 welcome.ftl이 되어 호출된다. 그런데, sitemesh에 의해서 바로 welcome.ftl이 보여지는 것이 아니라 main.jsp 데코레이터와 panelCount.jsp 데코레이터에 의해서 장식된 상태로 나오게 되는 것이다.



..

그런데 여기저기 찾아보다 보니까
사이트매쉬와 프리마커를 사용하기 위해서 다른 필터 클래스를 사용해야 한다 뭐 이런 내용이 있던데..

그냥 이렇게 사용하면 안되는건가??

이렇게 쓰면 프리마커와 사이트매쉬를 같이 사용하는 것이 아닌지 잘 모르겠다..--ㅋ


Posted by 용식

spring에서 freemarker 사용해 보기..
그냥 간단하게 사용해 보았다..

(아놔 이거 하고 있을 때 아닌데..괜히 손 대었다가 ㅠㅠ)

프리마커는..음.. UI단의 프레임워크라고 하면 될까..?

일단, 시작 해보자..

기본적인 spring의 설정은 되어있다고 가정하고..
[servletname]-serviet.xml은 action-config.xml로 설정한다.

우선은 라이브러리를 카피해야 하는데, freemarker.jar를 webapp lib에 넣는다.
spring 2.5.5를 받았다면 그 안에서 찾을 수 있다.

그리고, actions-config.xml을 설정한다.
(servletDispatcher가 바라보는 [servletname]-servlet.xml이랑 같은 녀석이다.. 이름만 다를뿐)

<!-- freemarker config -->
 <bean id="freemarkerConfig"
  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
  <property name="defaultEncoding" value="UTF-8" />
  <property name="freemarkerVariables">
   <map>
    <entry key="xml_escape" value-ref="fmXmlEscape" />
   </map>

  </property>
 </bean>

 <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />

 <!--
  View resolvers can also be configured with ResourceBundles or XML
  files. If you need different view resolving based on Locale, you have
  to use the resource bundle resolver.
 -->
 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  <property name="contentType" value="text/html; charset=UTF-8" />
  <property name="suffix" value=".ftl" />
  <property name="exposeSpringMacroHelpers" value="true" />
 </bean>



설정의 전부를 알지는 못하는데...
일단 , templateLoaderPath는 프리마커 템플릿 파일이 위치 할 곳을 지정한다고 보면 된다.
defaultEncoding 은 인코딩인데 resolver에도 인코딩 시켜주는 부분이 있다. 처음에는 resolver에서만 인코딩 설정을 해주었는데 계속 한글이 깨지길래 FreeMarkerConfigurer에도 설정 해주니 한글이 정상적으로 나왔다..

근데 뭔가 이상하긴 하다.. 저렇게 이중으로 설정하도록 만들어놨을까..? -_-ㅋ

그리고 freemarker.template.utility.XmlEscape 이게 무슨 역할을 하는건지는 아직 레퍼런스를 찾아보지는 못 했다....

더보기


일단,

  <property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
  <property name="defaultEncoding" value="UTF-8" />

요 두개만 설정해도 잘 돌아가긴 한다...


그리고 freemarker/welcome.ftl 파일을 만들어 놓는다.


그 다음 controller를 만들어보자.

@Controller
public class FreeMarkerTestController {
 Log logger = LogFactory.getLog(FreeMarkerTestController.class);

 @SuppressWarnings("unchecked")
 @RequestMapping("/welcome.gs")
 public ModelAndView test(HttpServletRequest request, HttpServletResponse response) throws Exception {
  HashMap map = new HashMap();
  map.put("key1","value1");
  map.put("key2", new Long(3L));

  logger.debug("in cotroller...");

  List list = new ArrayList();
  list.add("list1");
  list.add("list2");
  list.add("list3");
  list.add("list4");

  map.put("key3",list);

  String requestString = "myString";
  long requestLong = 5L;

  request.setAttribute("requestString",requestString);
  request.setAttribute("requestLong",requestLong);

  return new ModelAndView("/welcome","welcomeMap",map);

 }



몇가지 데이터 출력의 예를 살펴보기 위해 map과 list 그리고 request에 String과 long형을 담는다.

welcome.ftl을 만들어보자.

맵객체 꺼내기
${welcomeMap.key1}
${welcomeMap.key2}

request에서 값 받기
requestString : ${Request.requestString}
requestLong : ${Request.requestLong}

맵에 있는 list의 값 꺼내기
welcomeMap.key3[0] : ${welcomeMap.key3[0]}
welcomeMap.key3[1] : ${welcomeMap.key3[1]}
welcomeMap.key3[2] : ${welcomeMap.key3[2]}
welcomeMap.key3[3] : ${welcomeMap.key3[3]}

list 루프 돌려보기
 <#list welcomeMap.key3 as x3>
  ${x3}
  <#if x3 = "list3"><#break></#if>
</#list>


이렇게 하고 해보면 값들이 나오게 된다..

간단한 설정으로 사용 할 수 있는데, 까옥과장님 말씀으로는 그냥 java , jsp 익숙한 사람이
혼자 개발 할 때는 jsp로 하는게 훨씬 빠르다고 한다. 이거는 그냥 jsp와 java를 모르는 사람도 간단한 reference만으로도 데이터 구조만 알면 프론트 작업에 투입이 가능하다는 점이 장점으로 작용 될 수 있다고 합니다.

그외에도.. mvc를 강제 시켜 버리는 효과도 있을 것 같습니다.

일단 해보는게 목적이어서.. 저런 자세한 설정들은 좀 더 찾아봐야겠습니다..

혹시 아시는  분은 덧글로 알려주세요~~~


아... 만약

resolver가 이미

 <!-- bean id="jspViewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:cache="true" p:order="0" /-->


이런식으로 설정 되어 있다면 없애주셔야 제대로 ftl 파일을 찾아가더군요..


<참고: controller와 ftl의 소스 일부는 kkaok 님의 소스를 참고하였습니다.>
Posted by 용식