> Hello World !!!

     

@syaku

Struts2 Tiles FreeMarker 연동 : 스트럿츠2 타일즈 프리마커

written by Seok Kyun. Choi. 최석균

 Struts2 에 Tiles 와 FreeMarker 을 모두 연동하여 사용하기

** [2011/04/08] 헐 죄송합니다. Tiles 리설트 소스를 포함하지 않았네요;;; 이제서야 발견하다니...

※ 버전 : struts-2.2.1.1

* 아래의 내용은 스트럿츠2 와 타일즈를 기본적으로 사용하고 있다고 가정하고 작성하였다. 스트럿츠2와 타일즈 설명은 첨부하지 않음.

Struts2 는 MVC 모델2 역활을 하며, Tiles 레이아웃 엔진 그리고 FreeMarker 는 템플릿 엔진이다.

로직은 스트럿츠에서 리설트 타입을 tiles 주고, 서블릿 단에서 모든 페이지는 FreeMarker 로 파싱된다.
이로인해 어떤 페이지도 jsp 코드를 사용하지 않고 오로지 FreeMarker 를 사용할 수 있게 된다.

/lib
struts2-tiles-plugin-2.1.8.1.jar
tiles-api-2.0.6.jar
tiles-core-2.0.6.jar
tiles-jsp-2.0.6.jar
freemarker-2.3.16.jar


 web.xml

<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

  <servlet>
    <servlet-name>freemarker</servlet-name>
    <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
      
    <!-- Freemarker Servlet -->
    <init-param>
      <param-name>TemplatePath</param-name>
      <param-value>/</param-value>
    </init-param>
    <init-param>
      <param-name>NoCache</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>ContentType</param-name>
      <param-value>text/html; charset=UTF-8</param-value> <!-- Forces UTF-8 output encoding! -->
    </init-param>
      
    <!-- FreeMarker -->
    <init-param>
      <param-name>template_update_delay</param-name>
      <param-value>0</param-value> <!-- 0 is for development only! Use higher value otherwise. -->
    </init-param>
    <init-param>
      <param-name>default_encoding</param-name>
      <param-value>UTF-8</param-value> <!-- The encoding of the template files. -->
    </init-param>
    <init-param>
      <param-name>number_format</param-name>
      <param-value>0.##########</param-value>
    </init-param>

    <load-on-startup>0</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>freemarker</servlet-name>
    <!-- 중요 : *.html 파일은 모두 FreeMarker 로 로딩된다. -->
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>  

  <!-- struts2 -->
  <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

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

  <!-- tiles -->
  <context-param>
    <param-name> org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG </param-name> 
    <param-value>/WEB-INF/classes/tiles.xml</param-value> 
  </context-param>
  <listener>
    <listener-class>org.apache.struts2.tiles.StrutsTilesListener </listener-class> 
  </listener>

</web-app>


 Struts2 Tiles result 소스

[사용법]
test 클래스에서 public location = "template=test&body=/body.html"; 해주면 된다.
template 는 타일즈의 레이아웃 네임을 가르킨다. 나머지 파라메터는 put-attribute 반영된다.

# 스트럿츠2 액션맵퍼 소스

 <result-types>
 <result-type name="Tiles" class="com.syaku.common.TilesConfig" />
</result-types>

<action name="test" class="com.syaku.test">
  <result type="Tiles>${location}</result>
</action>

# TilesConfig 소스
/*
 * registered date 20110314
 * programmed by Seok Kyun. Choi. (최석균)
 * http://syaku.tistory.com
 */
package com.syaku.common;

import java.util.*;
import java.util.regex.*;
import java.text.*;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.opensymphony.xwork2.*;
import org.apache.struts2.dispatcher.*;
import org.apache.struts2.ServletActionContext;

import org.apache.log4j.Logger;

import org.apache.tiles.*;
import org.apache.tiles.access.*;

import org.apache.commons.lang.*;

public class TilesConfig extends StrutsResultSupport{
  private static Logger log = Logger.getLogger(TilesConfig.class);
  private String logtext = "";

  @Override
  protected void doExecute(String location, ActionInvocation invocation) throws Exception {
    location = conditionalParse(location, invocation);

    setLocation(location);
    if (!StringUtils.isEmpty(location)) {
      Pattern para_patten = Pattern.compile("^(.*)=(.*)$",Pattern.MULTILINE);
      String para = location.replaceAll("^[?&]","");

      String para_tokens[] = para.split("&");
      int para_cnt = para_tokens.length;

      logtext = StringUtils.join(new String[] {
      logtext ,
      "{TilesConfig}\r\n" , 
      "==========================================================================\r\n" , 
      "Syaku JAVA Library. Powered by Seok Kyun. Choi. http://syaku.tistory.com\r\n"
      });

      Map mapTiles = new HashMap();
      for (int i = 0; i < para_cnt; i++ ) {        
        Matcher para_matcher = para_patten.matcher(para_tokens[i]);
        String para_name = para_matcher.replaceAll("$1");
        String para_value = para_matcher.replaceAll("$2");

        mapTiles.put(para_name,para_value);

        logtext = StringUtils.join(new String[] {
        logtext ,
        "> Map set : " , para_name , " = " , para_value + "\r\n"
        });

      }

      String template = (String) mapTiles.get("template");

      mapTiles.put("template","");

      ServletContext servletContext = ServletActionContext.getServletContext();
      TilesContainer container = TilesAccess.getContainer(servletContext);
      HttpServletRequest request = ServletActionContext.getRequest();
      HttpServletResponse response = ServletActionContext.getResponse();
      AttributeContext attributeContext = container.getAttributeContext(request, response);

      for (Map.Entry entry: mapTiles.entrySet()) {
        String target = (String) entry.getKey();
        String path = (String) entry.getValue();

        if (!StringUtils.isEmpty(path)) {
          attributeContext.putAttribute(target, new Attribute(path));

          logtext = StringUtils.join(new String[] {
          logtext ,
          "> Tiles attribute get : " , target , " = " , path , "\r\n"
          });

        }

      }

      container.render(template, request, response);

      logtext = StringUtils.join(new String[] {
      logtext ,
      "> Tiles template get : " , template , "\r\n",
      "=========================================================================="
      });

      log.info(logtext);

    }

  }

}



 freemarker 적용

타일즈에서 <definition name="test" template="/layouts/layout.html"> 레이아웃이 되는 파일을 열자.

상단에 <#assign tiles=JspTaglibs["http://tiles.apache.org/tags-tiles"] /> 넣어주면 타일즈 태그 라이브러리를 사용할 수 있게 된다.

<@tiles.insertAttribute name="module"/> 이렇게 사용하면 된다.

Syaku Blog by Seok Kyun. Choi. 최석균.
posted syaku blog


http://syaku.tistory.com