FreeMark结合spring boot制作自定义标签

1.1 fileTag, 文件标签, 根据fileId值得到云端

代码如下:

package com.doui.business.service.tag;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

/**
 * freemark文件标签,用于页面根据文件id显示文件名和文件路径, 以及阿里云OSS文件获取
 * 
 * @author liaoly
 */

@Service("fileTag")
public class FileTag implements TemplateDirectiveModel {

    @Autowired
    private FileService FileService;

    @Override
    public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
            throws TemplateException, IOException {
        SimpleScalar value = (SimpleScalar) params.get("id");
        if(StringUtil.isEmpty(value.getAsString()))
            return;
        int id = Integer.parseInt(value.getAsString());
        SysFile file = FileService.getFileByid(id);
        BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_28).build();
        env.setVariable("file", beansWrapper.wrap(file));
        if (body != null) {
            body.render(env.getOut());
        } else {
            throw new RuntimeException("标签内部至少要加一个空格");
        }
    }

}

1.2在html页面上的写法如下所示:

<#list checkRawrecordLocation.fileList as file>


  •         <@fileTag id="${file.id}"> 
                 
                           150x150
                                   

                                         
    机房平面布局图

                                   

                 

             
     

  •  

    2.1. 枚举类标签, 根据枚举的key值, 和枚举类名得到枚举value(name)值

    代码如下所示:

    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.Map;

    import org.springframework.stereotype.Service;
    import freemarker.core.Environment;
    import freemarker.ext.beans.BeansWrapper;
    import freemarker.ext.beans.BeansWrapperBuilder;
    import freemarker.template.Configuration;
    import freemarker.template.SimpleScalar;
    import freemarker.template.TemplateDirectiveBody;
    import freemarker.template.TemplateDirectiveModel;
    import freemarker.template.TemplateException;
    import freemarker.template.TemplateModel;

    /**
     * freemark美枚举类标签
     * key : 枚举的value值, 一般是数据库中取出来的
     * enumType : 枚举类型(那种枚举)
     * 需要在EnumTypeEnum枚举中添加要用的枚举
     *
     * @author liaoly
     */

    @Service("enumTag")
    public class EnumTag implements TemplateDirectiveModel {

        @Override
        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                throws TemplateException, IOException {

            SimpleScalar key = (SimpleScalar) params.get("key"); //枚举的value值
            if(StringUtil.isEmpty(key.getAsString()))
                return;
            
            SimpleScalar enumType = (SimpleScalar) params.get("enumType"); //枚举类型(哪种枚举)
            if(StringUtil.isEmpty(enumType.getAsString()))
                return;
            
            String enumTypeStr = EnumTypeEnum.getName(enumType.getAsString());//得到枚举的全路径名
            
            Class clazz = null;
            Object Enum = null;
            try {
                clazz = Class.forName(enumTypeStr);
                byte parseByte = Byte.parseByte(key.getAsString());  //得到byte类型的value
                Method getNameMethod = clazz.getMethod("getName", byte.class);
                Enum = getNameMethod.invoke(null, parseByte); //得到指定value的name值(执行的是静态的getName(byte index)方法)
                
            } catch (Exception e) {
                return;
            }
            
            BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_28).build();
            
            env.setVariable("Enum", beansWrapper.wrap(Enum));

            if (body != null) {
                body.render(env.getOut());
            } else {
                throw new RuntimeException("标签内部至少要加一个空格");
            }
        }

    }

    2.2. 枚举类

    import com.doubi.framework.util.enumcommons.EnumAble;

    /**
     * 存储枚举类的枚举类
     *     注:
     *         主要是在自定义freeMark标签中使用
     *         标签中的enumType属性值为此枚举类的value值
     * @author liaoly
     *
     */
    public enum EnumTypeEnum implements EnumAble {
        
         type1("com.doubi.framework.enumtype.checkrecord.ExposureMode", "ExposureMode"),
         type2("com.doubi.framework.enumtype.checkrecord.SignLightType", "SignLightType"),
         type3("com.doubi.framework.enumtype.checkreport.BusinessType", "BusinessType"),
         type4("com.doubi.framework.enumtype.DataTemplateType", "DataTemplateType");
        
        
        // 成员变量
        private String name;
        private String value;

        // 构造方法
        private EnumTypeEnum(String name, String value) {
            this.name = name;
            this.value = value;
        }

        // get set 方法
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String index) {
            this.value = index;
        }

        public static String getName(String index) {
            for (EnumTypeEnum c : EnumTypeEnum.values()) {
                if (c.getValue().equals(index)) {
                    return c.name;
                }
            }
            return null;
        }

        @Override
        public String getValueByName() {
            return this.value;
        }

        @Override
        public String getNameByValue() {
            return this.name;
        }
    }

    2.3. 在html中使用该标签

    <@enumTag key="${checkRawDataLocation.data1}" enumType = "ExposureMode"> 
              ${Enum}

     

    3. 配置Freemarker视图解析器, 加入自定义标签

    package com.doubi.config;

    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import javax.annotation.PostConstruct;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
    import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
    import com.jagregory.shiro.freemarker.ShiroTags;

    import com.doubi.business.service.tag.EnumTag;
    import com.doubi.business.service.tag.FileTag;
    import freemarker.template.TemplateException;
    import freemarker.template.TemplateModelException;

    /**
     * 自定义一个ShiroTagFreeMarkerConfigurer继承Spring本身提供的FreeMarkerConfigurer,
     * 
     * 目的是在FreeMarker的Configuration中添加shiro的配置
     * 
     */
    @Component
    public class ShiroTagFreeMarkerConfig {

        private final Log log = LogFactory.getLog(getClass());

        @Autowired
        private FreeMarkerConfigurer freeMarkerConfigurer;

        @Autowired
        private FileTag FileTag;
        
        @Autowired
        private EnumTag enumTag;

        /**
         * 配置Freemarker视图解析器
         */
        // @Bean
        public FreeMarkerViewResolver freeMarkerViewResolver() {
            FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
            resolver.setPrefix("/html/");
            resolver.setSuffix(".html"); // 解析后缀为html
            resolver.setCache(false); // 是否缓存模板
            resolver.setRequestContextAttribute("request"); // 为模板调用时,调用request对象的变量名
            resolver.setOrder(0);
            log.info("定义freemarker的FreeMarkerViewResolver");
            return resolver;
        }

        @PostConstruct
        public void setSharedVariable() throws TemplateModelException {
            freemarker.template.Configuration config = freeMarkerConfigurer.getConfiguration();
            try {
                config.setSetting("classic_compatible", "true");
            } catch (TemplateException e) {
                e.printStackTrace();
            }
            config.setSharedVariable("shiro", new ShiroTags());
            config.setSharedVariable("fileTag", FileTag);
            config.setSharedVariable("enumTag", enumTag);
        }

        /**
         * 定义freemarker的配置
         * 
         * 加入自定义标签:fileTag , enumTag
         * 
         * 增加shiro标签支持
         */
        //@Bean
        public FreeMarkerConfigurer freeMarkerConfigurer() {
            FreeMarkerConfigurer a = new FreeMarkerConfigurer();
            try {
                a.afterPropertiesSet();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            }
            // a.getConfiguration().setSharedVariable("shiro", new ShiroTags());
            // a.setTemplateLoaderPath("classpath:/template");
            Map varMap = new HashMap();
            varMap.put("fileTag", FileTag);
            varMap.put("enumTag", enumTag);
            varMap.put("shiro", new ShiroTags());
            a.setFreemarkerVariables(varMap);

            log.info("定义freemarker的配置,加入自定义标签:fileTag");
            log.info("定义freemarker的配置,加入自定义标签:enumTag");
            return a;
        }
    }

     

    你可能感兴趣的:(后端)