2016년 9월 27일

Spring 기반 웹 프로그램 개발 Part 2 - Freemarker 사용하기

Spring MVC 의 장점중 하나는 여러 가지 View(JSP, Velocity, Freemarker .. 등) 기술을 손쉽게 사용할 수 있다는 점이다. 어떤기술의 View 를 사용하는 것은 개발자의 개인적인 취향이겠지만 과거부터 freemarker 기술을 사용해왔기 때문에 지금도 Freemarker 를 선호하고 있다. 

1. 환경 만들기 


  • Spring MVC 4.3.2.RELEASE
  • Freemarker 2.3.25-incubating 

Maven 을 사용하고 있어 프로젝트 pom.xml 파일 다음의 의존성을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependency>
      <groupid>org.springframework</groupid>
         <artifactid>spring-webmvc</artifactid>
        <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
   <groupid>org.springframework</groupid>
   <artifactid>spring-context</artifactid>
   <version>4.3.2.RELEASE</version>
  </dependency
  <dependency>
   <groupid>org.springframework</groupid>
   <artifactid>spring-context-support</artifactid>
   <version>4.3.2.RELEASE</version>
   <scope>test</scope>
  </dependency>
  <dependency>
    <groupid>org.freemarker</groupid>
    <artifactid>freemarker</artifactid>
    <version>2.3.25-incubating</version>
  </dependency>

2. 설정

기본적으로 설정은 어노테이션 또는 xml 방식이 있는데 개인적으로 xml방식을 더 선호하여 여기에서는 xml 방식으로 기술하였다. Freemarker 설정 context파일을 추가한다.
아래의 설정은 WEB-INF/template/ftl 경로에 freemarker 파일들이 위치하는 것으로 가정하였다.

freemarkSubsystemContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
 
 <!-- Freemarker 사용을위한 컴포넌트 정의 -->
  
 <beans:bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" id="freemarkerConfig">
  <beans:property name="preferFileSystemAccess" value="true"> </beans:property>
  <beans:property name="templateLoaderPath" value="/WEB-INF/template/ftl/"> </beans:property>
  <beans:property name="defaultEncoding" value="UTF-8"> </beans:property>
  <beans:property name="freemarkerVariables">
   <beans:map>
    <beans:entry key="xml_escape" value-ref="fmXmlEscape"></beans:entry>
    <beans:entry key="output_encoding" value="UTF-8"></beans:entry>
    <beans:entry key="whitespace_stripping" value="true"></beans:entry>
    <beans:entry key="template_update_delay" value="60"></beans:entry>  
    </beans:map>
  </beans:property>
  <beans:property name="freemarkerSettings">
   <beans:props>
    <beans:prop key="auto_import">/spring.ftl as spring</beans:prop>
   </beans:props>
  </beans:property>
</beans:bean>
  
 <beans:bean class="freemarker.template.utility.XmlEscape" id="fmXmlEscape"></beans:bean>
 
</beans:beans>  

위의 설정은 ViewResolver 부문이 제외되어 있는데 이부분은 아래와 같이 설정을 추가하면 된다. 이부분을 분리하여 기술한 것의 앞의 설정은 대부분의 경우에 수정이 요구되지 않지만 ViewResolver 는 프로젝트 환경에 따라 수정이 필요하여 분리하여 기술하였다.
servlet-context.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
  <!-- DispatcherServlet Context: 서블릿의 요청 처리를 위한 것들을 정의 -->
 
  <!-- Enables the Spring MVC @Controller programming model -->
  <mvc:annotation-driven></mvc:annotation-driven>
 
  <!-- Enables scan components (커스터마이징 필요 )  -->
  <context:component-scan base-package="sample"></context:component-scan>
 
  <!-- / 호출의 경우는 자동으로 index 파일을 호출하도록 설정 (커스터마이징 필요 )  -->
  <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
 
  <!-- 이미지, 자바스클립트, CSS 와 같은 정적 컨텐츠 요청(GET) 을 처리하기 위하여 설정 (커스터마이징 필요 ) -->
  <mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
  <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
  <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
   
  <!-- 뷰처리 위한 ViewResolver 정의  -->
  <beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver" id="beanNameViewResolver">
  <beans:property name="order" value="0">
  </beans:property>
  </beans:bean>
  
 
  <!-- 프로젝트 특성에 맞게 뷰를 수정하기 위하여 별도의 사용자 정의 View 클래스를 지정 ( 커스터마이징 필요 )  -->
  <beans:bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" id="freeMarkerViewResolver">
     <beans:property name="order" value="1"></beans:property>
     <beans:property name="cache" value="true"></beans:property>
     <beans:property name="prefix" value=""></beans:property>
     <beans:property name="suffix" value=".ftl"></beans:property>
     <beans:property name="viewClass" value="sample.spring.freemarker.SampleFreeMarkerView"></beans:property>
     <beans:property name="exposeSessionAttributes" value="true"></beans:property>
    <beans:property name="requestContextAttribute" value="rc"></beans:property>
    <beans:property name="exposeSpringMacroHelpers" value="true"></beans:property>
    <beans:property name="exposeRequestAttributes" value="true"></beans:property
  </beans:bean>
 
</beans:beans>

viewClass 는 org.springframework.web.servlet.view.freemarker.FreeMarkerView 클래스를 확장하여 다음과 같은 방법으로 손쉽게 만들수 있다.
sample.spring.freemarker.SampleFreeMarkerView.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package sample.spring.freemarker;
 
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
 
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;
 
/**
 * 스프링프레임워크에서 디폴트롤 사용하고 있는 FreeMarkerView 클래스를 커스터마이징함.
 *
 *
 * @author donghyuck
 *
 */
public class SampleFreeMarkerView extends FreeMarkerView {
 
  
 protected void exposeHelpers(Map<string object=""> model, HttpServletRequest request) throws Exception {
  BeansWrapper wrapper = (BeansWrapper)getObjectWrapper();
  populateStatics(wrapper, model);
 }
 
  
 /**
  * 모든 freemarker 템플릿에서 사용하게될 유틸리티들을 정의한다.
  *
  * @param wrapper
  * @param model
  */
 public void populateStatics(BeansWrapper wrapper, Map<string object=""> model){
   
  /**
   * 정적 Util / Helper 클래스들을 추가하여 ftl 파일에서 쉽게 필요한 유틸리티들을 사용할 수 있도록 한다.
   */
  TemplateHashModel staticModels = wrapper.getStaticModels();
  try {
   model.put("SecurityHelper", staticModels.get("neuro.honeycomb.util.SecurityHelper"));
   model.put("ApplicationContextHelper", staticModels.get("neuro.honeycomb.util.ApplicationContextHelper"));
   model.put("WebApplicationContextUtils", staticModels.get("org.springframework.web.context.support.WebApplicationContextUtils"));  
  } catch (TemplateModelException e) {
    
  }
   
  model.put("statics", BeansWrapper.getDefaultInstance().getStaticModels()); 
   
 }
}
 
</string></string>

3. 사용하기

이제 남은 것은 Spring Controller 가 FreeMarker 템플릿를 사용하여 화면을 출력하도록 하는 것이다. 사실 이부분이 지루한 부분이다.



댓글 없음:

댓글 쓰기