Lang/Freemarker

Jsp 에서 Freemarker 로 전환하기 [1] (w. springboot & tiles)

호형 2022. 3. 17. 17:36

Jsp와 Freemarker는 모두 template engine이다. 둘의 가장 큰 차이라고 생각되는 부분은 JavaEE에 종속적이냐 그렇지 않느냐의 차이인것 같다. 그리고 spring 진영에서 정식으로 지원을 하느냐 아니냐도 분명 큰 차이이다. 다들 알다시피 spring 진영에서는 Jsp를 정식지원하지 않는다. 이런 부분과 SPA가 유행을 하며 Jsp는 분명 쇠퇴기를 겪고 있다. 요즘 유행하는 SPA 적용 여건은 안되고 그렇다고 Jsp도 못쓰는 상황이면 Freemarker가 대안이 될 수 있다. 

이것끼리 전환을 하는게 무슨 의미가 있나 싶을수도 있지만 그런 요건이 있었고 이걸 필요로 하는 사람도 있을것이다. 

 

일단 필자의 환경은 springboot 2.5.x version 과 tiles 3.0.x version, maven 을 사용중이다. 원래는 jsp + tiles로 구성된 페이지를 freemarker + tiles로 전환을 하려고 한다. freemarker 자체적으로도 layout 구성이 가능하지만 최소한의 공수로 작업을 진행해야해서 tiles를 끼고 전환하였다. 

 

설명 순서는 jsp에서의 사용하던 방법과 freemarker에서 사용하는 방식을 기능별로 나열할 것이다. 


pom.xml

jsp

<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-jsp</artifactId>
    <version>${tiles.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>${jstl.version}</version>
</dependency>

freemarker

<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-freemarker</artifactId>
    <version>${tiles.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-extras</artifactId>
    <version>${tiles.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>${jstl.version}</version>
</dependency>

pom.xml 에서 달라지는점은 위와 같다. tiles와 연계해서 사용하기 때문에 tiles-jsp에서 tiles-freemarker로 변경하였다. 의외였던건 tomcat-embed-jasper나 jstl 같은것도 다 없앨수 있을줄 알았는데 freemarker를 사용한다해도 필요하다. freemarker에서도 JspTagLib 같은것들이 있는데 이런것들을 사용하기 위해서 필요한듯 하다. 


application.yml

jsp

server:
  servlet:
    jsp:
      init-parameters:
        development: 'true'

spring:
  mvc:
    view:
      prefix: /WEB-INF/jsp

freemarker

freemarker를 사용하기 위해 application.yml 에서 별도로 해줄일은 없다. (단 tiles를 사용하지 않고 순정 freemarker, 즉 spring-boot-starter-freemarker를 사용하는 경우라면 다음을 참조하자. 

 

Springboot application.properties (or .yml) 속성 종류

springboot의 설정 파일인 application.properties or application.yml 파일 내에서 다양한 속성을 지정할 수 있다. 내게 필요한 속성을 찾아서 프로젝트에 적용하면 된다. # =================================..

oingdaddy.tistory.com


Config (java 설정)

jsp

@Configuration
public class JspConfig extends SpringBootServletInitializer {
    
    @Bean
    public ConfigurableServletWebServerFactory configurableServletWebServerFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                super.postProcessContext(context);
                JspPropertyGroup jspPropertyGroup = new JspPropertyGroup();
                jspPropertyGroup.addUrlPattern("*.jsp");
                jspPropertyGroup.setPageEncoding("UTF-8");
                jspPropertyGroup.setScriptingInvalid("true");
                jspPropertyGroup.addIncludePrelude("/WEB-INF/jsp/common/common.jsp");
                jspPropertyGroup.setTrimWhitespace("true");
                jspPropertyGroup.setDefaultContentType("text/html");
                JspPropertyGroupDescriptorImpl jspPropertyGroupDescriptor = new JspPropertyGroupDescriptorImpl(
                        jspPropertyGroup);
                context.setJspConfigDescriptor(new JspConfigDescriptorImpl(
                        Collections.singletonList(jspPropertyGroupDescriptor), Collections.emptyList()));
            }
        };
    }
    
    @Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        tilesConfigurer.setDefinitions("classpath*:WEB-INF/jsp/layout-definition/tiles-layout.xml");
        return tilesConfigurer;
    }
    
    @Bean
    public UrlBasedViewResolver tilesViewResolver() {
        UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();
        urlBasedViewResolver.setViewClass(TilesView.class);
        return urlBasedViewResolver;
    }
}

jsp를 사용할 때 jsp 설정과 tiles 설정이다. tiles 설정은 일반적인 설정이고 jsp를 위와 같이 설정한건 common.jsp 및 contentType, encoding 정보 등을 모든 jsp에 참조시키기 위함이다. 

 

freemarker

@Configuration
public class FreeMarkerConfig{

    @Bean
    public TilesConfigurer tilesConfigurer() {

        String tilesDefinitionPath = "classpath*:/WEB-INF/freemarker/layout-definition/tiles-layout.xml";

        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        tilesConfigurer.setTilesInitializer(new CompleteAutoloadTilesInitializer() {
            @Override
            protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
                // BasicTilesContainerFactory
                return new CompleteAutoloadTilesContainerFactory() {
                    @Override
                    protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
                        List<ApplicationResource> retValue = new ArrayList<ApplicationResource>(1);
                        retValue.add(applicationContext.getResource(tilesDefinitionPath));
                        return retValue;
                    }

                    @Override
                    protected void registerAttributeRenderers(BasicRendererFactory rendererFactory, ApplicationContext applicationContext, TilesContainer container, AttributeEvaluatorFactory attributeEvaluatorFactory) {
                        super.registerAttributeRenderers(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
                        FreemarkerRendererBuilder freemarkerRenderer = FreemarkerRendererBuilder.createInstance();
                        freemarkerRenderer.setApplicationContext(applicationContext);
                        freemarkerRenderer.setParameter("defaultEncoding", "UTF-8");
                        freemarkerRenderer.setParameter("ClasspathTlds", "/META-INF/tld/tiles-jsp.tld, /META-INF/spring.tld");
                        freemarkerRenderer.setParameter("autoInclude", "/WEB-INF/freemarker/common/common.ftl");
                        freemarkerRenderer.setParameter("NoCache", "true");
                        rendererFactory.registerRenderer("freemarker", freemarkerRenderer.build());
                    }
                };
            }
        });
        return tilesConfigurer;
    }
	
    @Bean
    public UrlBasedViewResolver tilesViewResolver() {
        UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();
        urlBasedViewResolver.setViewClass(TilesView.class);
        urlBasedViewResolver.setRequestContextAttribute("rc");
        return urlBasedViewResolver;
    }
}

freemarker를 사용시에는 굳이 WEB-INF를 사용하지 않아도 된다. 하지만 일단 빠른 전환에 의의를 두었기 때문에 최대한 비슷한 구조로 변경을 하여 사용을 하게 되었다. 

tilesConfigure bean을 생성할때 어려움을 많이 겪었다. jsp와 설정부분에서 가장 많이 차이가 나는 부분이 아닐까 싶다. tiles가 init 되는 시점에 jsp와는 다르게 많은 일들을 이부분에서 처리를 해줘야 한다. 공통으로 쓸 ftl 파일이라던지 taglib에 대한 설정, encoding에 대한 설정 등등을 이곳에서 해준다. 아까 위에서 tiles와 결합하지 않은 순정 freemarker를 쓴다면 설정을 applcation.yml 에서 할수 있다고 하였는데 tiles와 결합하면 application.yml에 하는 설정을 이곳에서 해줘야 한다. 뭐든 순정을 쓰지 않으면 어려움을 겪는것 같다. 


tiles-layout.xml (tiles 설정)

tiles로 layout을 잡으니 당연 이부분에 대한 설정도 달라져야 한다. 

jsp

<definition name="oing.page.parent" template="/WEB-INF/jsp/layout/content.jsp">
    <put-attribute name="title" value="Template Project" type="string"/>    
    <put-attribute name="contents" value="/WEB-INF/jsp/layout/empty.jsp"/>
</definition>
<definition name="oing.page.*/*" extends="oing.page.parent">
    <put-attribute name="contents" value="/WEB-INF/jsp/{1}/{2}.jsp" />
</definition>

freemarker

<definition name="oing.page.parent" template="/WEB-INF/freemarker/layout/content.ftl" templateType="freemarker">
	<put-attribute name="title" value="Template Project" type="string"/>
	<put-attribute name="contents" value="/WEB-INF/freemarker/layout/empty.ftl"/>
</definition>
<definition name="WILDCARD:oing.page.*/*" extends="oing.page.parent">
	<put-attribute name="contents" value="/WEB-INF/freemarker/{1}/{2}.ftl" /><!-- 2 depth -->
</definition>

jsp에서 freemarker로 넘어갈때 tiles-layout.xml 파일에도 조금 변화가 있다. 단순하게 jsp만 ftl (freemarker 일반적인 확장자) 로 바꾸면 될줄 알았는데 definition 부에 templateType 이라는것도 넣어주고 (이건 java config > freemarker 예제 31줄과 매핑) 또한 */* 와 같은 wildcard가 잘 먹지 않아 freemarker에서는 WILDCARD:라는 접미어를 넣어주었다. 나머지는 거의 동일하다고 보면 된다. 


여기까지 했으면 jsp에서 freemarker로 전환을 할 준비는 어느정도 되었다고 보면 된다. 나머지는 jsp+jstl을 어떻게 freemarker 문법으로 전환을 하는지에 대한 부분이다. 

 

다음 글을 참조하도록 하자. 

 

Jsp 에서 Freemarker 로 전환하기 [2] (문법)

앞서 jsp to freemarker 전환에 대해 문법 외의 부분을 알아보았다. Jsp 에서 Freemarker 로 전환하기 (w. springboot & tiles) [1] Jsp와 Freemarker는 모두 template engine이다. 둘의 가장 큰 차이라고 생각되..

oingdaddy.tistory.com

 

끝!