Template engine and Freemarker
The goal of the template engine is "data + template = result"
Template engine effectively "decouples" data from presentation
template engine
Mainstream template engine
- Java Server Page(JSP)
- Freemarker
- Beetle
Freemarker
Freemarker is a free and open source template engine technology
Freemarker script is Freemarker Template Language
Freemarker provides a number of built-in functions to simplify development
JSP and Freemarker
JSP | Freemarker | |
---|---|---|
Official standard | yes | no |
Execution mode | Compiled type | Interpretive type |
Execution efficiency | high | low |
Development efficiency | low | high |
Expansion capability | weak | strong |
Data extraction | JSTL+EL | Built in label |
Freemarker quick start
Freemaker Chinese online manual: http://freemarker.foofun.cn/
Create a new ordinary java project, create a new lib folder, and import the jar package freemaker Jar and create a freemarker sample1. Jar under the freemaker package Java class and sample1 ftl file, double-click sample1 ftl file Eclipse will pop up a prompt to install the editing plug-in of ftl file. After installing the plug-in, only the file code will be highlighted. If it is not installed, it will not affect the development. Create a Computer class under the entity package as a subsequent test data class.
FTL value
The value of ${attribute name} can be used to calculate the attribute
${property name! Default value} if the property does not exist, use the default value
${attribute name? string} formatted output
Branch judgment
if branch judgment
switch branch judgment
freemarker.FreemarkerSample1.java
package freemarker; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Date; import java.util.HashMap; import java.util.Map; import entity.Computer; import freemarker.core.ParseException; import freemarker.template.Configuration; import freemarker.template.MalformedTemplateNameException; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateNotFoundException; public class FreemarkerSample1 { public static void main(String[] args) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException { //1. Load template Note that the passed in construction parameter specifies the version number of freemaker. Different versions of freemaker have different parsing syntax //Create core configuration object Configuration config = new Configuration(Configuration.VERSION_2_3_31); //Set load directory In freemarkersample1 Class class loads the specified ftl file, and the second parameter empty string represents the current package config.setClassForTemplateLoading(FreemarkerSample1.class, ""); //Get template object Template t = config.getTemplate("sample1.ftl"); //2. Create data Map<String,Object> data = new HashMap<String,Object>(); data.put("site", "Baidu"); data.put("url", "http://www.baidu.com"); data.put("date", new Date()); data.put("number", 2165464.565465); //You can also use complex data types Map info = new HashMap(); info.put("cpu", "i5"); Computer c1 = new Computer("1234567","ThinkPad",2,null,new Date(),12900f,info); data.put("computer",c1); //3. Generate output system Out is the output byte stream, while process needs to pass in the character stream. Use OutputStreamWriter to convert the byte stream into the character stream t.process(data, new OutputStreamWriter(System.out)); } }
sample1.ftl
<#--Freemarker value -- > ${site} ${url} <#--Default value -- > ${author!"Nonexistent property"} <#--Formatted output -- > ${date?string("yyyy year MM month dd day HH:mm:ss SSS")} ${number?string("0.00")} <#--In Freemarker, you only need "= =" to judge the equality of strings, instead of using equals -- > in java <#if computer.sn=="1234567"> Important equipment </#if> SN:${computer.sn} model:${computer.model} <#if computer.state==1> state:In use <#elseif computer.state==2> state:let ... lie idle <#elseif computer.state==2> state:Scrap </#if> <#switch computer.state> <#Case 1 > status: in use <#break> <#Case 2 > status: idle <#break> <#Case 3 > status: Scrap <#break> <#Default > status: invalid status </#switch> <#-- ?? Indicates whether the object is null and returns true / false -- > <#if computer.user??> user:${computer.user} </#if> Procurement time:${computer.dop?string("yyyy year MM month dd day")} Purchase price:${computer.price?string("0.00")} ----------------------- CPU:${computer.info["cpu"]} Memory:${computer.info["memory"]!"No memory information"}
entity.Computer.java
package entity; import java.util.Date; import java.util.Map; public class Computer { private String sn; //serial number private String model; private int state; //Status 1 - in use 2 - idle 3 - scrapped private String user; //User private Date dop; //Purchase date private Float price; private Map info; //Computer configuration information public Computer() {} public Computer(String sn, String model, int state, String user, Date dop, Float price, Map info) { super(); this.sn = sn; this.model = model; this.state = state; this.user = user; this.dop = dop; this.price = price; this.info = info; } public String getSn() {return sn;} public void setSn(String sn) {this.sn = sn;} public String getModel() {return model;} public void setModel(String model) {this.model = model;} public int getState() {return state;} public void setState(int state) {this.state = state;} public String getUser() {return user;} public void setUser(String user) {this.user = user;} public Date getDop() {return dop;} public void setDop(Date dop) {this.dop = dop;} public Float getPrice() {return price;} public void setPrice(Float price) {this.price = price;} public Map getInfo() {return info;} public void setInfo(Map info) {this.info = info;} }
List, iteration list, Map
Iterative variable + underlined index can obtain the index value of the current cycle
list iteration Map
Freemarkersample1 Data replacement in step 2 of Java
//2. Create data //Test data of iterative list Map<String,Object> data = new HashMap<String,Object>(); List<Computer> computers = new ArrayList(); computers.add(new Computer("1234567","ThinkPad",2,null,new Date(),12900f,new HashMap())); computers.add(new Computer("1234565","HP",2,"Hundred and six",new Date(),12900f,new HashMap())); computers.add(new Computer("1234568","DELL",2,"Small A",new Date(),12900f,new HashMap())); data.put("computers", computers); //Test data of iterative Map //HashMap is out of order, and LinkedHashMap can ensure that the data is stored in order for extraction Map computerMap = new LinkedHashMap(); for(Computer c:computers) { computerMap.put(c.getSn(), c); } data.put("computer_map", computerMap);
sample1.ftl
<#list computers as computer> Serial number:${computer_index+1} <#--Iterative variable_ Index saves the index of the loop -- > SN:${computer.sn} model:${computer.model} <#switch computer.state> <#case 1> state:In use <#break> <#case 2> state:let ... lie idle <#break> <#case 3> state:Scrap <#break> <#default> state:invalid state </#switch> <#if computer.user??> user:${computer.user} </#if> Procurement time:${computer.dop?string("yyyy year MM month dd day")} Purchase price:${computer.price?string("0.00")} CPU:${computer.info["cpu"]!"nothing CPU information"} Memory:${computer.info["memory"]!"No memory information"} ----------------------- </#list> ================================= <#list computer_map?keys as k> ${k}-${computer_map[k].model} ${computer_map[k].price?string("0.00")} <#--Others are not written by analogy -- > ----------------------- </#list>
Built in function (common)
Freemaker Chinese online manual: http://freemarker.foofun.cn/
Freemarkersample1 Data replacement in step 2 of Java
//2. Create data Map<String,Object> data = new HashMap<String,Object>(); data.put("name", "jackson"); data.put("brand", "bmw"); data.put("words", "first blood"); data.put("n", 34324.3432); data.put("date", new Date()); List<Computer> computers = new ArrayList(); computers.add(new Computer("1234567","ThinkPad",2,null,new Date(),12900f,new HashMap())); computers.add(new Computer("1234565","HP",2,"Hundred and six",new Date(),14900f,new HashMap())); computers.add(new Computer("1234568","DELL",2,"Small A",new Date(),12000f,new HashMap())); data.put("computers", computers);
sample1.ftl
${name?cap_first} ${brand?upper_case} ${brand?length} ${words?replace("blood","*****")} ${words?index_of("blood")} <#--Use? string implements the operation of ternary operator -- > ${(words?index_of("blood")!=-1)?string("Contains sensitive words","Does not contain sensitive words")} ${n?round} ${n?floor} ${n?ceiling} Co owned by the company ${computers?size}Computers First set:${computers?first.model} Last one:${computers?last.model} <#--Collection sorting function sort_by(), plus reverse, the reverse sort is the descending sort -- > <#list computers?sort_by("price")?reverse as c> ${c.sn}-${c.price} </#list>
Freemarker and Servlet integration
The project structure is as follows:
Import freemaker.exe from the WEB-INF/lib folder Jar package
Create a new employee in the ftl folder ftl, copy the prepared html code, and store static resources such as CSS, fonts and JS at the same level as WEB-INF
web.xml configuration freemaker
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>fm-web</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- servlet And freemarker Integration is by FreemarkerServlet Class implemented --> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <!-- Script file storage directory, access to.ftl End file mapped to/WEB-INF/ftl --> <init-param> <param-name>TemplatePath</param-name> <param-value>/WEB-INF/ftl</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> </web-app>
Employee.java employee data template class
package freemarker.servlet; public class Employee { private Integer empno; private String ename; private String department; private String job; private Float salary; public Employee() {} public Employee(Integer empno, String ename, String department, String job, Float salary) { super(); this.empno = empno; this.ename = ename; this.department = department; this.job = job; this.salary = salary; } public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Float getSalary() { return salary; } public void setSalary(Float salary) { this.salary = salary; } }
ListServlet.java background provides data
package freemarker.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class ListServlet */ @WebServlet("/list") public class ListServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public ListServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List list = new ArrayList(); list.add(new Employee(7332,"Xiao Wang","Marketing Department","Customer representative",5654f)); list.add(new Employee(8832,"Small B","R & D department","Operation and maintenance engineer",7000f)); request.setAttribute("employee_list", list); // Request forwarding jump request.getRequestDispatcher("/employee.ftl").forward(request,response); } }
employee.ftl list iteration list display data
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Employee list</title> <link href="css/bootstrap.css" type="text/css" rel="stylesheet"></link> <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <style type="text/css"> .pagination { margin: 0px } .pagination > li > a, .pagination > li > span { margin: 0 5px; border: 1px solid #dddddd; } .glyphicon { margin-right: 3px; } .form-control[readonly] { cursor: pointer; background-color: white; } #dlgPhoto .modal-body{ text-align: center; } .preview{ max-width: 500px; } </style> </head> <body> <div class="container"> <div class="row"> <h1 style="text-align: center">Employee information form</h1> <div class="panel panel-default"> <div class="clearfix panel-heading "> <div class="input-group" style="width: 500px;"> </div> </div> <table border=1 class="table table-bordered table-hover"> <thead> <tr> <th>Serial number</th> <th>Employee number</th> <th>full name</th> <th>department</th> <th>post</th> <th>wages</th> <th> </th> </tr> </thead> <tbody> <#-- employee_ The list value range is found from request, session and servletContext in turn -- > <#list employee_list as emp> <tr> <td>${emp_index+1}</td> <td>${emp.empno?string("0")}</td> <td>${emp.ename}</td> <td>${emp.department}</td> <td>${emp.job}</td> <td style="color: red;font-weight: bold">¥${emp.salary?string("0.00")}</td> </tr> </#list> </tbody> </table> </div> </div> </div> </body> </html>
Visit / list on the web page to forward the request to employee FTL displays web pages and dynamically binds background data