本文共 4366 字,大约阅读时间需要 14 分钟。
关于Freemark的原理:
模板引擎 + 数据 ------------------> 页面输出
一、什么是模板引擎,为什么要用模板引擎
在B/S程式设计中,常常有美工和程序员二个角色,他们具有不同专业技能:美工专注于表现——创建页面、风格、布局、效果等等可视元素;而程序员则忙于创建程式的商业流程,生成设计页面要显示的数据等等。
很多时候,要显示的资料在设计的时候并不存在,它们一般是在运行时由程式产生的,比如执行“价格不高于800NT的USB Disk”查询的返回结果。这种技术需求产生了JSP等Scriptlet,JSP十分强大,但是也常常被滥用,并导致一些不良的后果
模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,我们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其他文本,我们称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码。
模板和嵌入JSP的HTML是不同的,模板指令只有很有限的编程能力,可以避免混入商业逻辑。
FreeMarker缺点:
1. 性能没有Velocity高,学习起来没有Velocity简单
2. 需要花费时间重新学习
3. FreeMarker中不能读取值为null的变量,会报错,必须要设置默认值或者判断
4. 模板修改之后,如果没有更新模板生成的HTML,会看到过期的页面
5. MyEclipseIDE插件的效果不太好
环境Maven,需要freemark.jar,pom文件如下:
步骤:4.0.0 com.lgy freemarker war 0.0.1-SNAPSHOT freemarker Maven Webapp http://maven.apache.org junit junit 4.10 test javax.servlet servlet-api 2.4 provided javax.servlet.jsp jsp-api 2.0 provided org.freemarker freemarker 2.3.22 freemarker
1.编写模板文件:
说明:person为一个对象freemark 测试 ${person.id!"aaa"} ----------------------------------------------- <#if person.id??> wo qu <#else> yufa piaoyi ----------------------------------------------- <#if person.flag> ye li shame ------------------------------------------------ <#switch person.username> <#case "aa"> 1 <#break> <#case "hahah"> 2 <#break> <#default> 3
package com.lgy.entry;public class Person { private Integer id; private String username; private String password; private Boolean flag = true; public Boolean getFlag() { return flag; } public void setFlag(Boolean flag) { this.flag = flag; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}第二步(核心代码说明):
package com.lgy.test;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.util.HashMap;import java.util.Map;import org.junit.Before;import org.junit.Test;import com.lgy.entry.Person;import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateException;/* * 模板 + 数据 = 输出 */public class FreeMarkerTest { private Configuration configuration; @SuppressWarnings("deprecation") @Before public void init() { configuration = new Configuration(); try { configuration.setDirectoryForTemplateLoading(new File("F://Users/Maven/freemarker/src/main/webapp/freemark")); } catch (IOException e) { e.printStackTrace(); } } @Test public void FreemarkTest() { OutputStreamWriter out = null; File file = new File("F://Users/Maven/freemarker/src/main/webapp/index.html"); //创建一个合适的Configration对象 try { out = new OutputStreamWriter(new FileOutputStream(file)); //创建模版对象 Template t = configuration.getTemplate("index-string.html"); Person person = new Person(); person.setUsername("hahah"); //构造填充数据的Map Mapmap = this.getData("person", person); //在模版上执行插值操作,并输出到制定的输出流中 t.process(map, out); out.close(); System.out.println("生产完成"); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } finally { if(out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public Map getData(String key, Object value) { Map map = new HashMap (); map.put(key, value); return map; } }