freemarker自定义标签

本文内容:
1. 基于SpringMVC整合Freemarker的自定义标签实例。
2. TemplateDirectiveModle 的详解
3. 自定义标签使用的小技巧

一、基于SpringMVC整合Freemarker的自定义标签实例
1、jar包依赖,配置到项目pom.xml


<dependency>
    <groupId>org.freemarkergroupId>
    <artifactId>freemarkerartifactId>
    <version>2.3.23version>
dependency>

2、Spring 的配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
    <context:component-scan base-package="org.oc.freemarker.directives">context:component-scan>

    <bean id="freemarkerConfig"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        
        <property name="templateLoaderPath" value="/WEB-INF/template/" />

        <property name="freemarkerSettings">
            <props>
                <prop key="defaultEncoding">UTF-8prop> 
            props> 
        property>

        
        <property name="freemarkerVariables">
            <map>
                <entry key="sitemap" value-ref="siteMapDirective" />
            map>
        property> 
    bean>

beans>

3、实现TemplateDirectiveModel接口

package org.oc.freemarker.directives;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.core.ParseException;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNotFoundException;

public abstract class SiteMapDirective implements TemplateDirectiveModel{


    @Override
    public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)throws TemplateException, IOException {
        /*这里实现你对标签的处理逻辑*/
        /*获取参数,TemplateScalarModel 为获取字符串,TemplateNumberModel 获取数值类型*/
        TemplateScalarModel smT =  (TemplateScalarModel) params.get("title");
        TemplateNumberModel nmN =  (TemplateNumberModel) params.get("num");
        String title = smT.getAsString();
        Integer num = (Integer) nmN.getAsNumber();

        /*向模版上下文设置数据变量,采用Freemarker建议的数据封装类*/
        List strs = new ArrayList();
        strs.add("数据1");
        strs.add("数据2");
        DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(new Version("2.3.22")); 
        DefaultObjectWrapper objectWrapper = builder.build();
        try {
            environment.setVariable("strs", objectWrapper.wrap(strs));
        } catch (TemplateModelException e) {
            e.printStackTrace();
        }

        /*渲染模版*/
        if(body!=null)
            body.render(env.getOut());

    }

}

MVC的配置文件


<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:context="http://www.springframework.org/schema/context"  
 xmlns:p="http://www.springframework.org/schema/p"  
 xmlns:mvc="http://www.springframework.org/schema/mvc"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
      http://www.springframework.org/schema/context  
      http://www.springframework.org/schema/context/spring-context.xsd  
      http://www.springframework.org/schema/mvc  
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  

       
     <mvc:annotation-driven />  
       
     <context:component-scan base-package="org.oc.controller" />  


    
    <bean id="freemakerViewResolver"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
        
        <property name="viewNames">
            <array>
                <value>*.ftlvalue>
            array>
        property>
        <property name="contentType" value="text/html; charset=UTF-8" />
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="exposeSpringMacroHelpers" value="false" />
        <property name="requestContextAttribute" value="request" />
        
        <property name="order" value="1" />
    bean>


beans>  

实现以上的方式,就可以在页面中使用自定变量了

<@sitemap>
<#list strs as str>
    ${str!}
#list>
sitemap>

二、TemplateDirectiveModle 的详解
1、接口方法 execute

    /**
     * 执行这个自定义指令; 当该自定义指令在模版中被调用则会调用本方法;
     *
     * @param env 当前模版内容处理的运行环境. 请记住你可以访问的输出流Writer 通过Environment的getOut()方法。 
     * @param params the parameters (if any) passed to the directive as a 
     * map of key/value pairs where the keys are {@link String}-s and the 
     * values are {@link TemplateModel} instances. This is never 
     * null. If you need to convert the template models to POJOs,
     * you can use the utility methods in the {@link DeepUnwrap} class.
     * @param loopVars an array that corresponds to the "loop variables", in
     * the order as they appear in the directive call. ("Loop variables" are out-parameters
     * that are available to the nested body of the directive; see in the Manual.)
     * You set the loop variables by writing this array. The length of the array gives the
     * number of loop-variables that the caller has specified.
     * Never null, but can be a zero-length array.
     * @param body an object that can be used to render the nested content (body) of
     * the directive call. If the directive call has no nested content (i.e., it's like
     * <@myDirective /> or <@myDirective></@myDirective>), then this will be
     * null.
     *
     * @throws TemplateException If any problem occurs that's not an {@link IOException} during writing the template
     *          output.
     * @throws IOException When writing the template output fails.
     */
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body);

你可能感兴趣的:(freemarker)