Servlet 整合 freemarker、如何在 freemarker 中自定义标签

1.引入核心依赖

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>

2.编辑 web.xml 文件(使用 3.0 的版本)

    <servlet>
        <servlet-name>freemarkerServlet</servlet-name>
        <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
        <init-param>
            <param-name>TemplatePath</param-name>
            <param-value>/</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>freemarkerServlet</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>

3.编写一个 servlet(至此,整合 Servlet 已经结束)

@WebServlet("/test01")
public class TestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Template template = FreemarkerUtils.getTemplate("2.ftl");
        Map<String, Object> rootMap = new HashMap<>();
        rootMap.put("username", "tomtom");
        rootMap.put("addr", "nanjing");
        req.getRequestDispatcher("template/f01.ftl").forward(req, resp);
    }
}

4.开始自定义一个标签

  1.1 首先编写一个工具类

public class FreemarkerUtils {

    private static Configuration configuration;

    private static Configuration buildCofiguration() {
        if(null == configuration) {
            configuration = new Configuration(Configuration.VERSION_2_3_23);
            configuration.setSharedVariable("origin", new MySimpleDirective());
            File dirFile = new File("D:/ij-workspace/xxx/my-web/src/main/resources/");
            try {
                configuration.setDirectoryForTemplateLoading(dirFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return configuration;
        }
        return configuration;
    }

    public static Template getTemplate(String filename) {
        try {
            Template template = buildCofiguration().getTemplate(filename);
            return template;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

  1.2 实现自定义指令

public class MySimpleDirective implements TemplateDirectiveModel {
    @Override
    public void execute(Environment env, Map map, TemplateModel[] loopVars, TemplateDirectiveBody body)
            throws TemplateException, IOException {
        System.out.println("MySimpleDirective..." + " , map is : " + map);
        Writer out = env.getOut();
        int count = Integer.parseInt(map.get("count") + "");
        for(int i = 0; i < 1; i++) {
            //可以在内容强加上前置(也可以直接拼接在 下面的 content 中)
            out.write(" predix ");
            //将 body 中内容交给 writer 处理,但并不由输出流写出。而是将内容取出,此时可以针对内容做任何处理
            MyWriter myWriter = new MyWriter();
            body.render(myWriter);
            String content = myWriter.getContent();
            out.write(content);
            //可以在内容后加上后置
            out.write(" suffix");
        }
    }

    static class MyWriter extends Writer {
        private StringBuilder builder = new StringBuilder();
        public String getContent() {
            return builder.toString();
        }

        @Override
        public void write(char[] cbuf, int off, int len) throws IOException {
            //这里是分段显示的,每个插值表达式作为一个段,比如模板中的内容 "---${username}---${addr}" 将分成 5 段
//            writer.write(new String(cbuf));
            builder.append(new String(cbuf));
        }

        @Override
        public void flush() throws IOException {
            System.out.println("flush");
        }

        @Override
        public void close() throws IOException {
            System.out.println("close");
        }
    }
}

  1.3 编写 2.ftl,内容如下:

    <@origin count=3 warn=5>--- ${username} --- ${addr}</@origin>

  1.4 编写测试类

    public static void main(String[] args) throws Exception {
        Template template = FreemarkerUtils.getTemplate("2.ftl");
        Map<String, Object> rootMap = new HashMap<>();
        rootMap.put("username", "tomtom");
        rootMap.put("addr", "nanjing");
        Writer out = new OutputStreamWriter(System.out);
        template.process(rootMap, out);
        System.out.println("
over");
    }

  1.5 相关参考链接

https://freemarker.apache.org/docs/pgui_datamodel_directive.html

https://blog.csdn.net/mahoking/article/details/51589935

原文地址:https://www.cnblogs.com/zhangjieatbky/p/13838571.html