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("\nover");
}
1.5 相关参考链接
https://freemarker.apache.org/docs/pgui_datamodel_directive.html

浙公网安备 33010602011771号