In-depth explanation of Freemarker from 0 to 1

Freemarker

  • FreeMarker is a template engine: that is, a general-purpose tool for generating output text (HTML web pages, emails, configuration files, source code, etc.) based on templates and data to be changed. It is not intended for end users, but a Java class library, a component that programmers can embed in the products they develop.

  • Templates are written in FreeMarker Template Language (FTL). It's a simple, dedicated language, not a full-fledged programming language like PHP. That means preparing the data to be displayed in the real programming language, such as database query and business operation, and then the template displays the prepared data. In the template, you can focus on how to present the data, while outside the template you can focus on what data to display.
    insert image description here
    What are the commonly used java template engines?
    Jsp, Freemarker, Thymeleaf, Velocity, etc.
    1. Jsp is dedicated to Servlet and cannot be used alone.
    2. Thymeleaf is a new technology with relatively powerful functions, but its execution efficiency is relatively low.
    3. Velocity has not been updated since it was updated to version 2.0 in 2010. Spring Boot officially no longer supports this after version 1.4. Although Velocity was iterated in version 2017, it was too late.

Getting Started Case

rely

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
 </dependency>
 <!-- apache 对 java io 的封装工具库 -->
<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
 </dependency> 

configuration file

server:
  port: 8881 #服务端口
spring:
  application:
    name: freemarker-demo #指定服务名
  freemarker:
    cache: false  #关闭模板缓存,方便测试
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
    suffix: .ftl               #指定Freemarker模板文件的后缀名

case:

  • Create a Student class
@Data
public class Student {
    
    
    private String name;//姓名
    private int age;//年龄
}
  • create template
    • resourcesCreate templates under
    • Create a template file under templates01-basic.ftl
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello World!</title>
</head>
<body>
<b>普通文本 String 展示:</b><br><br>
Hello ${name} <br>
<hr>
<b>对象Student中的数据展示:</b><br/>
姓名:${stu.name}<br/>
年龄:${stu.age}
<hr>
</body>
</html>
  • create controller
@Controller
public class HelloController {
    
    

    @GetMapping("/basic")
    public String test(Model model) {
    
    


        //1.纯文本形式的参数
        model.addAttribute("name", "freemarker");
        //2.实体类相关的参数
        
        Student student = new Student();
        student.setName("小明");
        student.setAge(18);
        model.addAttribute("stu", student);

        return "01-basic";
    }
}
  • startup class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FreemarkerDemotApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(FreemarkerDemotApplication.class,args);
    }
}
  • Test: http://localhost:8881/basic
    insert image description here

freemarker basics

Types of Basic Grammar

1. Comments, namely <#-- -->, the content between them will be ignored by freemarker

<#--我是一个freemarker注释-->

2. Interpolation: In the .. part, freemarker will replace the {..} part with the real value, and freemarker will replace the {..} part with the real value..section , _f ree ma r k er will replace {…} with real values

Hello ${name}

3. FTL instructions: Similar to HTML tags, add # before the name to distinguish, and Freemarker will parse the expression or logic in the tag.

<# >FTL指令</#> 

4. Text, only text information, these are not freemarker comments, interpolation, and FTL instructions, which will be ignored and parsed by freemarker, and the content will be output directly.

<#--freemarker中的普通文本-->
我是一个普通的文本

Collection instructions (List and Map)

$ <#list model里面的名 as 变量名> </#list>

Student stu2 = new Student();
        stu2.setName("小红");
        //将两个对象模型数据存放到List集合中
        List<Student> stus = new ArrayList<>();
        stus.add(stu1);
        //向model中存放List集合数据
        model.addAttribute("stus",stus);
<#list stus as stu>
        <tr>
            <td>${stu_index+1}</td>
            <td>${stu.name}</td>
        </tr>
 </#list>

${stt_index}:h Get the subscript, the default is 0 start

  • Map
 HashMap<String,Student> stuMap = new HashMap<>();
        stuMap.put("stu1",stu1);
        stuMap.put("stu2",stu2);
        // 3.1 向model中存放Map数据
        model.addAttribute("stuMap", stuMap);
<a href="###">方式一:通过map['keyname'].property</a><br/>
输出stu1的学生信息:<br/>
姓名${stuMap['stu1'].name}<br/>
年龄${stuMap['stu1'].age}<br/>
<br/>
<a href="###">方式二:通过map.keyname.property</a><br/>
输出stu2的学生信息:<br/>
姓名:${stuMap.stu2.name}<br/>
年龄:${stuMap.stu2.age}<br/>
  • Traversing the Map
<a href="###">遍历map中两个学生信息:</a><br/>
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#list stuMap?keys as key >
        <tr>
            <td>${key_index}</td>
            <td>${stuMap[key].name}</td>
            <td>${stuMap[key].age}</td>
            <td>${stuMap[key].money}</td>
        </tr>
    </#list>
</table>
  • Summarize
  1. getMap
    map['keyname'].property
    map.keyname.property
  2. Traversing the Map
<#list userMap?key as key>
	${stuMap[key].name}
</#list>

if instruction (judgment)

<#if >
 <#else>
</#if>
  • It is required to make the data font of 'Xiaohong' in the list collection be red
<#list stus as stu >
        <#if stu.name='小红'>
            <tr style="color: red">
                <td>${stu_index}</td>
                <td>${stu.name}</td>
                <td>${stu.age}</td>
                <td>${stu.money}</td>
            </tr>
        <#else >
            <tr>
                <td>${stu_index}</td>
                <td>${stu.name}</td>
                <td>${stu.age}</td>
                <td>${stu.money}</td>
            </tr>
        </#if>
    </#list>
  • Note that the = sign and == are used in the same way

Freemarker operator

Arithmetic operations are fully supported in FreeMarker expressions, and the arithmetic operators supported by FreeMarker include:

  1. mathematical operator
  • Addition: +
  • Subtraction:-
  • Multiplication: *
  • Division: /
  • Modulo (remainder): %
  1. comparison operator
  • = or ==: Determines whether two values ​​are equal.
  • !=: Determine whether two values ​​are not equal.
  • >Or gt: determine whether the value on the left is greater than the value on the right
  • >= or gte: determine whether the value on the left is greater than or equal to the value on the right
  • < or lt: determine whether the value on the left is smaller than the value on the right
  • <= or lte: determine whether the value on the left is less than or equal to the value on the right

comparison operator note

  • = and != can be used on strings, numbers and dates to compare equality
  • = and != both sides must be the same type of value, otherwise an error will be generated
  • String "x", "x ", "X" comparison is not equal. Because FreeMarker is exact comparison
  • Other operators work on numbers and dates, but not on strings
  • Using gt and other letter operators instead of > will have a better effect, because FreeMarker will interpret > as the end character of the FTL tag
  • This can be avoided by using parentheses like: <#if (x>y)>
  1. Logical Operators
  • Logical AND: &&
  • Logical OR: ||
  • logical NOT:!

Null handling

  1. Null value processing
    To judge whether a variable exists use "??"
  <#if stus??>
    <#list stus as stu>
    	......
    </#list>
    </#if>
  1. Default values ​​for missing variables use "!"
  • Use ! to specify a default value, and display the default value when the variable is empty
    Example: ${name!''} means to display an empty string if name is empty. Two single quotes indicate empty

  • If it is a nested object, it is recommended to use () to enclose it.
    Example: ${(stu.name)!''} means that if stu or bestFriend or name is empty, an empty string will be displayed by default.

built-in function

  • Built-in function syntax format:变量+?+函数名称
  1. and to the size of some collection${集合名?size}
  2. Date formatting:
    1. Display year, month, and day:${today?date}
    2. Display hours, minutes and seconds: ${today?time}
    3. Display date + time: ${today?datetime}
    4. Custom format: ${today?string("yyyy year MM month")}
  3. function c
model.addAttribute("point",11223344556)`

${point}The display effect is: 112,223,334,556
${point?c}The display effect is: 11223344556
4. Convert the JSON string into an objecteval

<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
<#assign data=text?eval />
开户行:${data.bank}  账号:${data.account}

static test

insert image description here
Preparations required in the early stage: xxftl and data model

server:
  port: 8881 #服务端口
spring:
  application:
    name: freemarker-demo #指定服务名
  freemarker:
    cache: false  #关闭模板缓存,方便测试
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
    suffix: .ftl               #指定Freemarker模板文件的后缀名
    template-loader-path: classpath:/templates #获取
    
  • xxx.ftl
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello World!</title>
</head>
<body>

<#-- list 数据的展示 -->
<b>展示list中的stu数据:</b>
<br>
<br>
<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#list stus as stu >
        <#if stu.name='小红'>
            <tr style="color: red">
                <td>${stu_index}</td>
                <td>${stu.name}</td>
                <td>${stu.age}</td>
                <td>${stu.money}</td>
            </tr>
        <#else >
            <tr>
                <td>${stu_index}</td>
                <td>${stu.name}</td>
                <td>${stu.age}</td>
                <td>${stu.money}</td>
            </tr>
        </#if>
    </#list>
</table>
<hr>

<#-- Map 数据的展示 -->
<b>map数据的展示:</b>
<br/><br/>
<a href="###">方式一:通过map['keyname'].property</a><br/>
输出stu1的学生信息:<br/>
姓名${stuMap['stu1'].name}<br/>
年龄${stuMap['stu1'].age}<br/>
<br/>
<a href="###">方式二:通过map.keyname.property</a><br/>
输出stu2的学生信息:<br/>
姓名:${stuMap.stu2.name}<br/>
年龄:${stuMap.stu2.age}<br/>

<br/>
<a href="###">遍历map中两个学生信息:</a><br/>
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#list stuMap?keys as key >
        <tr>
            <td>${key_index}</td>
            <td>${stuMap[key].name}</td>
            <td>${stuMap[key].age}</td>
            <td>${stuMap[key].money}</td>
        </tr>
    </#list>
</table>
<hr>

</body>
</html>
  • test
@SpringBootTest(classes = FreemarkerDemoApplication.class)
@RunWith(SpringRunner.class)
public class FreemarkerTest {
    
    
    @Autowired
    private Configuration configuration;

    @Test
    public void test() throws IOException, TemplateException {
    
    
        Template template = configuration.getTemplate("02-list.ftl");
        /**
         * 第一个参数: 模型数据
         * 第二个参数: 输出流
         */
        template.process(getData(),new FileWriter("e:/list.html"));
    }

    private Map getData() {
    
    
        Map<String, Object> map = new HashMap<>();

        //小强对象模型数据
        Student stu1 = new Student();
        stu1.setName("小强");
        stu1.setAge(18);
        stu1.setMoney(1000.86f);
        stu1.setBirthday(new Date());

        //小红对象模型数据
        Student stu2 = new Student();
        stu2.setName("小红");
        stu2.setMoney(200.1f);
        stu2.setAge(19);

        //将两个对象模型数据存放到List集合中
        List<Student> stus = new ArrayList<>();
        stus.add(stu1);
        stus.add(stu2);

        //向map中存放List集合数据
        map.put("stus", stus);


        //创建Map数据
        HashMap<String, Student> stuMap = new HashMap<>();
        stuMap.put("stu1", stu1);
        stuMap.put("stu2", stu2);
        //向map中存放Map数据
        map.put("stuMap", stuMap);

        //返回Map
        return map;
    }
}

Guess you like

Origin blog.csdn.net/m0_72568513/article/details/131866606