Java模板引擎之Freemarker学习笔记

这是一篇学习自慕课网视频--《Java模板引擎之Freemarker》的笔记,感谢慕课网和慕课老师们的无私帮助。写这篇博客的目的是为以后工作中使用freemarker,遇到问题方便查阅。

 什么是Freemarker

  1. Freemarker是一款模板引擎
  2. Freemarker不是web框架,它只是一个Java组件,提供MVC设计模式中视图层的功能

数据模型+模板输出=HTML(输出)

Java模板引擎之Freemarker学习笔记_第1张图片 数据模型+模板输出=HTML(输出)

创建Springboot集成Freemarker的项目

  1. 打开IntelliJ IDEA,依次点击File > new Project ,弹出窗口中选择Spring Initializr,出现如下窗口Java模板引擎之Freemarker学习笔记_第2张图片

 Java模板引擎之Freemarker学习笔记_第3张图片

2.依次点击Next,输入项目名称,团队名称,其他默认之后继续Next,出现如下窗口

 Java模板引擎之Freemarker学习笔记_第4张图片

3.如上窗口,依次勾选Core -> DevTools(Springboot热部署)、Web -> Web(Springmvc)、Template Engines -> Freemarker,选好后点击Next ,即可创建一个包含Freemarker的Springboot项目,此创建过程需要联网。

Java模板引擎之Freemarker学习笔记_第5张图片

以上是pom文件包含的依赖。

 4.项目创建好后,目录结构如下

Java模板引擎之Freemarker学习笔记_第6张图片

5.打开application.yaml,加入如下配置项

# 配置freemarker
spring:
  freemarker:
    # 设置模板后缀名
    suffix: .ftl
    # 设置文档类型
    content-type: text/html
    # 设置页面编码格式
    charset: UTF-8
    # 设置页面缓存
    cache: false
    # 设置ftl文件路径
    template-loader-path: classpath:/templates/
    check-template-location: true
    expose-request-attributes: true
    expose-session-attributes: true
    request-context-attribute: request
  # 设置静态文件路径,js,css等
  mvc:
    static-path-pattern: /static/**

server:
  port: 8080
  servlet:
    context-path: /springboot-java

6.创建HelloController,在controller中写入一个控制页面跳转的方法,如下

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class HelloController {

    @RequestMapping("/")
    public String welcome(HttpServletRequest request){
        request.setAttribute("name","Mr.Yang");
        return "index";
    }
}

7.在templates文件夹下,新建index.ftl文件,写入如下内容

<#assign base=request.contextPath />



    
    首页
    


Hello! ${name},glad to see you!
${base}

8.启动DemoApplication,运行Springboot容器

看到如上内容,表示项目已经在tomcat上启动成功了,项目名称是demo,端口是8080,访问地址是http://localhost:8080/demo 

9.访问http://localhost:8080/demo,即可看到Freemarker引擎生成的html页面

Java模板引擎之Freemarker学习笔记_第7张图片

 至此,Springboot集成Freemarker项目创建完毕。

Freemarker内置指令

  1. 变量创建和赋值和运算
    <#assign a=10 />
    ${a + 100}

     

  2.  自定义对象User变量的属性值获取

    • 对象
    • ${(userObj.name)!"默认值"}

     

  3.  输出富文本内容

    user.setBrief("我只想早点下班。对不起,你是程序员!");
    
    
    • 输出富文本内容
    • ${(userObj.brief)!?html}

     

  4.  集合Map的遍历

    • 集合map的遍历
    • <#list map?keys as key> ${key}:${map[key]}

     

  5.  if语法

    • if else指令
    • <#if myList?exists> <#list myList as item> ${item}
    • if多条件 || , && , !
    • <#assign var='python'> <#if var == 'python' || var == 'java' || var?length==6> python or java

     

  6.  switch语法

    switch case break default

      <#assgin var == 110 /> <#switch var> <#case 10> <#case 11> 10 or 11
      <#break> <#case 100> 100
      <#break> <#default> other

     

  7.  string基本操作命令

      <#assign a='hello' /> <#assign b='world'/>
    • 连接
    • ${a + b}
    • 截取
    • ${(a + b)?substring(5,8)}
    • 长度
    • ${(a + b)?length}
    • 大写
    • ${(a + b)?upper_case}
    • 小写
    • ${(a + b)?lower_case}
    • index_of
    • ${(a + b)?index_of('w')}
    • last_index_of
    • ${(a + b)?last_index_of('o')}
    • replace
    • ${(a + b)?replace('o','xx')}

     

Freemarker自定义函数

  1. 编辑index.ftl文件,使用sort_int函数对集合list进行升序排序

    自定义函数

    1,自定义函数(整数排序 sort_int)

      <#assign myList=[2,3,4,5,1,8,9,8,7]/>
    • 未排序
    • <#list myList as item> ${item},
    • 已排序
    • <#list sort_int(myList) as item> ${item},

     

  2. 在model.tag包下,创建SortMethod类实现TemplateModelEX接口,它就是实现自定义排序函数的类。

    package com.example.demo.model.tag;
    
    public class SortMethod implements TemplateMethodModelEx {
    
        @Override
        public Object exec(List arguments) throws TemplateModelException {
            //获取第一个参数
            SimpleSequence arg0=(SimpleSequence)arguments.get(0);
            List list=arg0.toList();
    
            Collections.sort(list,new Comparator(){
                @Override
                public int compare(BigDecimal o1, BigDecimal o2) {
                    return o1.intValue()-o2.intValue(); //升序
                }
            });
    
            return list;
        }
    }
    

     

  3. 在控制器方法中,加入sort_int函数变量。

    @RequestMapping("/")
        public String welcome(HttpServletRequest request){
            request.setAttribute("name","Mr.Yang");
            request.setAttribute("sort_int",new SortMethod());
            return "index";
        }

     

  4. 运行springboot,查看localhost:8080/demo,结果如下则自定义函数创建成功。 

     Java模板引擎之Freemarker学习笔记_第8张图片

     

 list排序内置函数和常用指令

item_index:此变量用于list遍历指令内,表示当前item所在下标,从0开始计数。

sort :内置的list集合排序函数

reverse: 内置的list集合反序函数

size :获取list集合的大小

myList[3]:获取下标为3的集合元素

<#assign base=request.contextPath />



    
    首页
    


List的指令

1,list常用指令

    <#assign myList=[2,3,4,5,1,8,9,8,7] /> <#list myList?sort?reverse as item> ${item_index} : ${item}
    ${myList?size}
    ${myList[3]}

Freemarker自定义指令

  1. 创建index2.ftl,写入如下内容,使用自定义指令role,自定义以@开头
    <#assign base=request.contextPath />
    
    
    
        
        index2
        
    
    
    

    自定义指令

    1,用户123456是否拥有admin角色,并且返回admin的权限

      <@role user='123456' role='admin'; result1 , result2> <#if result1> 我的角色是admin
      我拥有的权限是: <#list result2 as item> ${item},

     

  2.  在model.tag包下创建RoleDirectiveModel类,实现TemplateDirectiveModel接口,它就是创建role指令的实现类。

    package com.example.demo.model.tag;
    
    
    @Component
    public class RoleDirectiveModel implements TemplateDirectiveModel {
        /**
         *
         * @param environment 环境变量
         * @param params 指令参数(存储你所需要的值,随便是什么Key-Value你懂的)
         * @param loopVars 循环变量 返回值
         * @param templateDirectiveBody 指令内容
         * 除了params外,其他的都能是Null。
         * @throws TemplateException
         * @throws IOException
         */
        @Override
        public void execute(Environment environment, Map params, TemplateModel[] loopVars, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
            System.out.println("=========");
            TemplateScalarModel user=(TemplateScalarModel)params.get("user");
            TemplateScalarModel role=(TemplateScalarModel)params.get("role");
    
            if("123456".equals(user.getAsString()) && "admin".equals(role.getAsString()) ){
                loopVars[0]=TemplateBooleanModel.TRUE;
            }
    
            List otherRights=new ArrayList<>();
            otherRights.add("add");
            otherRights.add("update");
            otherRights.add("delete");
            loopVars[1]=new SimpleSequence(otherRights);
    
            templateDirectiveBody.render(environment.getOut());
        }
    }
    

     

  3.  在config包下创建FreeMarkerAutoConfiguration类,这是一个java配置类,它用来将自定义指令role注册到freemarker的共享变量中,这样在模板文件中就可以使用role指令了。

    package com.example.demo.config;
    
    import com.example.demo.model.tag.RoleDirectiveModel;
    import com.example.demo.model.tag.SortMethod;
    import freemarker.template.TemplateModelException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.PostConstruct;
    
    @Slf4j
    @Configuration
    public class FreeMarkerAutoConfiguration {
    
        @Autowired
        private freemarker.template.Configuration configuration;
        @Autowired
        private RoleDirectiveModel roleDirectiveModel;
        @Autowired
        private SortMethod sortMethod;
    
        @PostConstruct
        public void setSharedVariable() {
            try {
                //自定义标签
                configuration.setSharedVariable("role", roleDirectiveModel);
                configuration.setSharedVariable("sort_int",sortMethod);
            } catch (Exception e) {
                log.error("Custom tags failed to load:{}", e.getMessage());
            }
        }
    }
    

     

  • 重启Springboot项目,看到如下内容则表示自定义指令运行成功。 Java模板引擎之Freemarker学习笔记_第9张图片

     FreeMarker内建函数

  1.  处理字符串内建函数
    //见名知义哈
    
    1.substring , cap_first , ends_with , contains
    
    2. date , datetime , time
    
    3. starts_with , index_of , last_index_of , split , trim

    代码示例

    内建函数

      1,字符串内建函数

      <#list "a|b|c|d"?split("|") as item>
    • ${item}
    • <#assign var1="01/03/2017"?date("MM/dd/yyyy")> <#assign var2="15:05:30"?time("HH:mm:ss")> <#assign var3="2016-12-31 03:05 PM"?datetime("yyyy-MM-dd hh:mm")>
    • ${var1}
    • ${var2}
    • ${var3}

     

  2.  处理数字的内建函数

    1. string , x?string("0.##")
    
    2. round , floor , ceiling
    

    代码示例

    2,数字类型内建函数

    <#assign numVar1 = 314.5662 />
  3. ${numVar1?string("0.##")}
  4. //四舍五入 结果314.57
  5. ${numVar1?round}
  6.  

  7.  

    处理List的内建函数

     

    1. first , last, seq_contains, seq_index_of
    
    2. size, reverse, sort, sort_by
    
    3. chunk

    代码示例

    3,list内建函数

    <#assign listVar1 = [1,2,3,4,11,12,13,14,21,22,23,24] />
  8. ${listVar1?chunk(4)?size} <#list listVar1?chunk(4)?last as item>
  9. ${item}
  10.  

  11. 其他内建函数

    1. is函数:is_string, is_number, is_method
    
    2. (), has_content函数
    
    3. eval求值

    代码示例

    4,其他内建函数

    <#assign sVar='hello' />
  12. ${sVar?is_number?string('yes','no')}
  13. ${sVar?has_content?string('yes','no')}
  14. ${'1+2'?eval}
  15. Macro宏指令、function函数指令 

 

  1. 下面是macro指令和function指令的语法
    #macro nested return 章节
        macro语法:
            <#macro macro_name param1 param2 param3 paramN...>
                template_code ${param1}
                <#nested />
            
    
         调用
         <@macro_name param1="value1" param2="value2" />
    
         <@macro_name param1="value1" param2="value2">
            nested_template
         
    
    #function语法
     <#function function_name param1 param2>
        <#return param1+param2>
     
    
     调用
     ${doAdd(100,100)}
    

     

  2. 新建index3 .ftl文件,在其中使用macro宏指令创建共用模板代码,使用function指令创建自定义函数。

    <#assign base=request.contextPath />
    
    
    
        
        index3
        
        
    
    
    

    macro nested return 实战demo

    1,macro :宏指令

    • 栗子1:无参数的macro
    • <#macro test> 我是无参数的macro <@test/>
    • 栗子2:有参数的macro
    • <#macro test1 param1 param2> 我是有参数的macro,param1 = ${param1},param2 = ${param2} <@test1 param1="java" param2="python" />
    • 栗子3:有默认值参数的macro
    • <#macro test2 param1 param2="python"> 我是有参数的macro,param1 = ${param1},param2 = ${param2} <@test2 param1="java" />
    • 栗子4:有多个参数的macro
    • <#macro test3 param1 param2="python" paramExt...> 我是有参数的macro,param1 = ${param1}, param2 = ${param2}
      ${paramExt['param3']}
      ${paramExt['param4']} <@test3 param1="java" param2="hello python" param3="javascript" param4="nodejs"/>

    2,nested

      <#macro test param1 = "java"> ${param1}
      <#nested param1,"我的nested 参数">
    • 调用
    • <@test param1="java"; loopVar1, loopVar2> hello ${loopVar1} , ${loopVar2} <@test param1="python";loopVar1> hello ${loopVar1}

    3,函数

      <#function doAdd param1 param2> <#return param1+param2>
    • 调用
    • 你好,我是调用 ${doAdd(100,100)}

     

  3. 运行springboot项目,在浏览器中访问 localhost:8080/index3,可看到如下结果:Java模板引擎之Freemarker学习笔记_第10张图片

 

你可能感兴趣的:(FreeMarker学习笔记,FreeMarker,Springboot)