记录-三步走FreeMarker Template学习

简介:

  学习Java模版引擎FreeMarker截至到现在20个小时,记录一下整个学习过程,发现学习中的问题,同时留下对FreeMarker最初时的认知,待假以时日项目组的数据和视图层分离使用FreeMarker的时侯不至于因为时间长了不知从何开始,又要重新走一步Hello FreeMarker的过程,又能够温故知新发现更多,更奇妙的东西。


j_0001.gifHello FreeMarker

 1.百度百科:FreeMarker http://baike.baidu.com/link?url=204dZtLs4TQhVPp2V_gFfJrv9EzewLu3R4AXHOWIhr9CLxbgnxu0AewyWDmoxWhqGtNH0Dk9PlF-Wpd-rLPpwa

   很牛,很强大,能做表现出,也能当工具使,Java语言编写的模版引擎且对Web容器无与依赖性。

 2.找一篇博文看看Iteye 曾Java著名社区

http://relive123-yahoo-com-cn.iteye.com/blog/818013

   基本了解FreeMarker基本写法,功能特性,怎么弄个Hello FreeMarker出来

 3.出自何门何派,官方网站走一圈

http://freemarker.org/index.html

   惊喜,有部分中文文档,窃喜,英文文档也很清晰可读。

 4.尝试我的Hello FreeMarker

  • 新建一个web工程,将freemarker.jar放置lib(classpath)目录

  • 配置web.xml文件,配置方式和普通的Servlet配置相同


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
< servlet >
         < servlet-name >freemarker</ servlet-name >
         < servlet-class >freemarker.ext.servlet.FreemarkerServlet</ servlet-class >
         < init-param >
             < param-name >TemplatePath</ param-name >
             < param-value >/</ param-value >
         </ init-param >
         < init-param >
             < param-name >NoCache</ param-name >
             < param-value >true</ param-value >
         </ init-param >
         < init-param >
             < param-name >ContentType</ param-name >
             < param-value >text/html</ param-value >
         </ init-param >
         < init-param >
             < param-name >template_update_delay</ param-name >
             < param-value >0</ param-value >
         </ init-param >
         < init-param >
             < param-name >locale</ param-name >
             < param-value >zh_CN</ param-value >
         </ init-param >
         < init-param >
             < param-name >default_encoding</ param-name >
             < param-value >UTF-8</ param-value >
         </ init-param >
         < init-param >
             < param-name >output_encoding</ param-name >
             < param-value >UTF-8</ param-value >
         </ init-param >
         < init-param >
             < param-name >date_format</ param-name >
             < param-value >yyyy-MM-dd</ param-value >
         </ init-param >
         < init-param >
             < param-name >time_format</ param-name >
             < param-value >HH:mm:ss</ param-value >
         </ init-param >
         < init-param >
             < param-name >datetime_format</ param-name >
             < param-value >yyyy-MM-dd HH:mm:ss</ param-value >
         </ init-param >
     </ servlet >

  注意:初始化的参数很多可以根据需要配置,或者在使用的时候在进行设置,在FreeMarker的帮助文档中写的很清楚。

195238806.png

  • 创建一个test1.html模版内容如下:

1
< div ><#assign v="hello freemarker"> ${v}</ div >
  • 部署web工程打开test1.html

    195551374.png

  • OK,模版就是这么搞定,关于更多的指令等信息有第二步的博文,也有第三步的官方清晰可读的文档。



    下面是在探索中的一些总结:

  • FreeMarker数据模型+模版==输入内容,可产生友好的表现

  • 数据模型有简单数据类型,Sequence类型(Java的List,Array),Hasher类型(Map, Bean等),总体概况数据模型是一棵树,保证数据以树的形式组织,从而就有个root的概念

  • 实际使用过程中遇到的问题有很好的页面异常信息显示,并仔细阅读文档都可以解决,注意留心每一个条目说明后的Note信息

  • 特性丰富:内置的特性strings,numbers,booleans,dates等;指令特性声明,导入,包含,循环,判断,分支,功能函数,表达式等高频率使用

  • 最后一条,学习一个没有接触过的东西,还是从Hello XX开始是一个良好的起端,另外与其在网上找各种帖子,代码段学习不如试试这三步,末了看看官方文档初学遇到的问题基本都有清晰的说明并且能够发现更多的东西。



j_0001.gif一个例子说明官方文档的优越性

   问题:自定义方法模型

   解决:官方文档中有TemplateMethodModel接口配合源代码模仿一个判断字符串A是否包含字符串B的方法

   源码:

   接口TemplateMethodModel继承TemplateModel接口;

   接口TemplateMethodModelEx继承了TemplateMethodModel接口;

   TemplateMethodModelEx接口的实现中有一个类是:SimpleMethodModel看看他的源码就豁然开朗知道如何去实现我们自己的SimpleMethodIsContainsModel类。

   类:

1
2
3
4
public  final  class  SimpleMethodModel  extends  SimpleMemberModel
     implements
     TemplateMethodModelEx,
     TemplateSequenceModel

   核心实现方法:


1
public  Object exec(List arguments)

   自己实现:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  com.broncho.fm;
import  java.util.List;
import  freemarker.template.TemplateMethodModel;
import  freemarker.template.TemplateModelException;
@SuppressWarnings ( "deprecation" )
public  class  SimpleMethodIsContainsModel  implements  TemplateMethodModel {
     @Override
     public  Object exec(List arguments)  throws  TemplateModelException {
         if  (arguments.size() !=  2 ) {
             throw  new  TemplateModelException(
                     "template model arguments is wrong !" );
         }
         return  ((String) arguments.get( 0 )).contains((CharSequence) arguments
                 .get( 1 ));
     }
}

    用法测试:

    编写一个servlet和一个模版

    1.Servlet实现


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package  com.broncho.fm;
import  java.io.IOException;
import  java.util.HashMap;
import  java.util.Map;
import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;
import  freemarker.template.Template;
import  freemarker.template.TemplateException;
public  class  TestMethodServlet  extends  HttpServlet {
     private  static  final  long  serialVersionUID = -8862621014491094117L;
     private  Template template;
     public  TestMethodServlet() {
         super ();
     }
     public  void  destroy() {
         super .destroy();
     }
     public  void  doGet(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         doPost(request, response);
     }
     public  void  doPost(HttpServletRequest request, HttpServletResponse response)
             throws  ServletException, IOException {
         response.setContentType( "text/html" );
         response.setCharacterEncoding( "UTF-8" );
         Map<String, SimpleMethodIsContainsModel> root =  new  HashMap<String, SimpleMethodIsContainsModel>();
         root.put( "iscontains" new  SimpleMethodIsContainsModel());
         try  {
             template.process(root, response.getWriter());
         catch  (TemplateException e) {
             e.printStackTrace();
         }
     }
     public  void  init()  throws  ServletException {
         try  {
             template = FreeMarkerTemplateFactory.getConfiguration(
                     this .getServletContext(),  "/" ).getTemplate( "block2.ftl" );
         catch  (IOException e) {
             e.printStackTrace();
         }
     }
}

      这里servlet依赖一个工具助手类


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package  com.broncho.fm;
import  javax.servlet.ServletContext;
import  freemarker.template.Configuration;
/**
  * Template Configuration
  *
  */
public  class  FreeMarkerTemplateFactory {
     public  static  Configuration cfg;
     public  static  void  init() {
         if  (cfg ==  null ) {
             cfg =  new  Configuration();
         }
     }
     public  static  Configuration getConfiguration(ServletContext servletContext,
             String path) {
         init();
         if  (path ==  null ) {
             path =  "/" ;
         }
         cfg.setServletContextForTemplateLoading(servletContext, path);
         return  cfg;
     }
}

    2.模版


1
2
3
4
5
6
< div >
         <#assign arg1="tomcat" arg2="cat">
         ${arg1} is contains ${arg2}
         < br />
         ${iscontains(arg1, arg2)}
     </ div >

    说明:root很重要,创建的SimpleMethodIsContainsModel对象要作为方法使用,而在模版在的方法名就是root这个hasher的key值。

    3.部署运行

203943988.png

   运行之后报一大堆错误,摘取前部分重点信息,可以看出模版中的部分信息输出,计算后的结果没有输出。

   上面这段异常提示信息的信息量足够大,这也是个人感觉FreeMarker很牛的一点。

   分析:

  • isContains方法的返回值是boolean类型,FreeMarker template不具备boolean自动转string;

  • 不能转还不能说FreeMarker template能力不行,接下来他给的解释说 boolean_format设置为true,false,恰好这是他默认的计算语言格式,这么一说就不能怪他了;

  • 还没完,他给了两个处理建议,一个是解决当前问题,另一个是解决此类转换的方法,更人性化的是他还给了如何写的例子,如:${myboolean?string('yes','no');

  • 至此,还有惊喜的是FreeMarker Template异常提示的位置相当精确,而且还具备从哪里开始错就在哪那里开始报的优秀品质。

  修改后的模版信息:

 

1
2
3
4
5
6
< div >
         <#assign arg1="tomcat" arg2="cat">
         ${arg1} is contains ${arg2}
         < br />
         ${iscontains(arg1, arg2)?string("true","false")}
     </ div >

   

   末尾:实际上官方的帮助文档这一点写的很清楚,唯一要做的是习惯读英文资料。



本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1332579,如需转载请自行联系原作者

相关文章
|
4月前
|
人工智能 Java
AI大模型----SpringBoot添加放行最简单的方式@AuthAccess,问题库构思,概念title,答案text,搜索search
AI大模型----SpringBoot添加放行最简单的方式@AuthAccess,问题库构思,概念title,答案text,搜索search
|
6月前
|
搜索推荐 JavaScript Java
springboot+vue人职匹配推荐系统(源码+文档)
本文介绍了一个基于SpringBoot的人职匹配推荐系统,由Java开发,使用SpringBoot框架,JDK1.8,MySQL 5.7+数据库,前端技术包括Node.js和Vue。系统支持用户、管理员和企业三种角色,分别有不同的功能模块: - 用户可管理应聘信息和应聘状况,包括查看和修改个人资料。 - 管理员负责用户、企业、岗位、应聘信息、应聘状况和平台费用的全面管理。 - 企业可管理岗位信息、应聘信息、应聘状况及平台费用。 此外,系统还提供用户注册、登录功能,并在首页展示企业、岗位信息等。项目源码和部署详情可联系作者获取。
|
XML 移动开发 前端开发
SpringBoot员工管理的项目——SpringBoot首页定制的操作和国际编码操作(课时十五)
SpringBoot员工管理的项目——SpringBoot首页定制的操作和国际编码操作(课时十五)
112 0
SpringBoot员工管理的项目——SpringBoot首页定制的操作和国际编码操作(课时十五)
|
XML 前端开发 Java
说一下springBoot的起步环境--包含论文必备的完整流程图
说一下springBoot的起步环境--包含论文必备的完整流程图
|
前端开发 Java
#yyds干货盘点 前后端springboot和vue+实现部门的增删改功能记录
#yyds干货盘点 前后端springboot和vue+实现部门的增删改功能记录
69 0
|
监控 前端开发 算法
牛啊!长这么大还是头一次见24W字的SpringBoot从入门到实战文档
牛啊!长这么大还是头一次见24W字的SpringBoot从入门到实战文档! 不服还真不行,因为这份文档包含的内容是又全又新,而且还特别高深,从入门到实战的内容全都有!!
|
XML 缓存 Java
页面静态化技术---Freemarker介绍
页面静态化技术---Freemarker介绍
页面静态化技术---Freemarker介绍
|
Java 数据库连接 mybatis
不仔细听课找错找到哭,解决could not find “mybatis.xml“
不仔细听课找错找到哭,解决could not find “mybatis.xml“
不仔细听课找错找到哭,解决could not  find “mybatis.xml“
|
JavaScript Java 数据库连接
17、SpringBoot2.0中初始化数据和不校验 html 标签(十七)
我们在做测试的时候经常需要初始化导入一些数据,如何来处理呢?会有两种选择,一种是使用 Jpa,另外一种是 Spring JDBC 。两种方式各有区别下面来详细介绍。
160 0
|
存储 缓存 Java
《SpringBoot系列十三》:图文精讲@Conditional条件装配实现原理
《SpringBoot系列十三》:图文精讲@Conditional条件装配实现原理
212 0
《SpringBoot系列十三》:图文精讲@Conditional条件装配实现原理