page contents

java freemarker的模板和表达式教程

本文讲述了Java freemarker的模板和表达式教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-07-LX5jGJiN64a225c37743c.png

本文讲述了Java freemarker的模板和表达教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

一 概述

在低代码探索:Java 模板引擎技术 中,我们介绍了freemarker的概念和简单使用示例。本篇会详细介绍一下freemarker中的表达式,这在使用时很重要。我们通过模板定义要生成的页面框架,通过表达式来实现参数占位/替换,输入变量的首字母大/小写转换,以及for循环遍历等等。通过模板与表达式的配合,生成所需的页面/代码文件。

二 模板

关于模板的介绍,可以先看看freemarker在线手册的内容。FTL (即FreeMarker template language),就是freemarker为编写模板设计的非常简单的编程语言。

2.1 FTL介绍

模板(FTL编程)是由如下部分混合而成的:


文本:文本会照着原样来输出。


插值:这部分的输出会被计算的值来替换,相当于模板中的“变量”。插值由 ${ and } 所分隔(或者 #{ and },这种风格已经不建议再使用了,使用 number_format 设置项 和 the string 内建函数 来代替。对于计算机使用 (也就非本地的格式化)的格式化,使用 c 内建函数 (比如 number?c)。)。例如,我们有两个变量x和y,x=2.582 而 y=4,那么常用的插值表达式和对应的取值如下面所示:


#{x}       <#-- 2.582 -->

#{y}       <#-- 4 -->

#{x; M2}   <#-- 2.58 -->

#{y; M2}   <#-- 4    -->

#{x; m1}   <#-- 2.6 -->

#{y; m1}   <#-- 4.0 -->

#{x; m1M2} <#-- 2.58 -->

#{y; m1M2} <#-- 4.0  -->

FTL 标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。


注释:注释和HTML的注释也很相似,但它们是由 <#-- 和 -->来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。


2.2 模板示例

下面是手册中提供的一个HTML页面的模板示例:其中,蓝色代表文本,橘黄色代表插值(${user}),黄色代表FTL标签(<#list animals ...),而绿色是注释, [BR]是为了在页面上显式可见的换行:

attachments-2023-07-JYSx5aVs64a2258349af3.png

FTL有几点注意事项需要特别指出:


1、FTL区分大小写,例如 list 是指令的名称,而List不是(切记!),${name} 和 ${Name} 或 ${NAME} 也不相同。


2、插值 仅仅可以在 文本(或字符串表达式)中使用。


3、FTL 标签 不可以在其他 FTL 标签 和 插值中使用。比如, 这样做是 错误 的: <#if <#include 'foo'>='bar'>...</#if>


4、注释 可以放在 FTL 标签 和 插值中。示例:


<h1>Welcome ${user <#-- The name of user -->}!</h1>[BR]

<p>We have these animals:[BR]

<ul>[BR]

<#list <#-- some comment... --> animals as <#-- again... --> animal>[BR]

...

2.3 指令

FTL的指令是通过标签来调用,例如上面用到的<#list animals as animal>,使用到了list这个指令,代表遍历list中的每个变量。除了list之外,常用的还有<#if>


FTL的指令有两种类型: 预定义指令 和 用户自定义指令。详细说明可以参见链接,这里不再赘述,有疑问可以共同探讨。


2.4 表达式

FTL的表达式主要包括 直接确定值(字符串、数字、布尔值、序列、值域、哈希表)、检索变量、字符串操作、序列操作、哈希表操作等等。在定义模板时,使用最多的是直接确定值(字符串、数字),其次是检索变量和字符串操作。

检索变量示例:我们在外层定义好一个user对象,包含name, age等属性,那么在模板中应用时,可以通过 ${user.name}, ${user.age}来获取对应的值并替换到模板中对应的位置;

字符串操作示例:字符串连接:"Hello ${user}!" ;获取一个字符:name[0];字符串切分: 包含结尾: name[0..4],不包含结尾: name[0..<5],基于长度(宽容处理): name[0..*5],去除开头: name[5..]。

2.5 插值

插值是用来给 表达式 插入具体值然后转换为文本(字符串)。用我们更熟悉的表述,就是模板中的占位符,用来标记某个位置是一个变量,在生成代码时,可以通过传入我们定义好的值,模板进行识别并完成替换,从而生成我们最终想要的文件。


插值的使用格式: ${expression},这里的 expression 可以是所有种类的表达式(比如 ${100 + x})。


完整的示例和说明还是推荐查看手册:插值。


三 模板使用和生成示例

接下来,我们还是通过demo来阐述freemarker模板定义到生成文件的整个过程,jar包的引入方式在低代码探索:Java 模板引擎技术中已经有过说明,这里只列举模板和代码部分。

3.1 模板定义

test.java.ftl:


package ${packageName};


public class ${className} {


<#if colList??>

<#list colList as col>

    private ${col.type} ${col.name};


</#list>


<#list colList as col>

    public ${col.type} get${col.name?cap_first}(){

        return ${col.name};

    }


    public void set${col.name?cap_first}(${col.type} ${col.name}){

        this.${col.name}=${col.name};

    }

</#list>

</#if>

}

这个模板定义了一个典型的实体类,也就是POJO。属性列表我们通过colList参数传入,并在外层加了if 的判断,避免参数为空的情况;对于list中的每个变量,都是一个col对象,里面有type 和 name两个属性,上述模板先逐个生成 private Integer id; xxx 这些字段,然后再依次生成对应的getId setId。。。 方法。

因为get set方法需要的是变量名的首字母大写,所以这里还使用了 get${col.name?cap_first}来对首字母进行大写处理。

3.2 column实体类定义

package com.freemark.demo.entity;


import lombok.Builder;

import lombok.Data;


@Data

@Builder

public class Column {

  private String type;

  private String name;

}

Column用于封装参数,有type和name两个属性。 这里为了简化代码 引入了lombok,在pom.xml中增加相关依赖引入即可:


<dependency>

  <groupId>org.projectlombok</groupId>

  <artifactId>lombok</artifactId>

  <version>1.18.22</version>

</dependency>

3.3 生成代码方法

主要就是完成参数封装,模板加载和生成方法与上一篇内容相似。

package com.freemark.demo.templates.util;


import com.freemark.demo.entity.Column;

import freemarker.template.Configuration;

import freemarker.template.Template;


import java.io.*;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;


public class FreemarkerTest {


  private static final String TEMPLATE_PATH = "src/main/java/com/freemark/demo/templates";


  private static final String CLASS_PATH = "src/main/java/com/freemark/demo";


  public static void main(String[] args) {

    // 创建freeMarker配置实例

    Configuration configuration = new Configuration();

    Writer out = null;

    try {


      // 设置模版路径

      configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));

      // 创建数据模型

      Map<String, Object> dataMap = new HashMap<>();

      dataMap.put("packageName", "com.freemark.demo");

      dataMap.put("className", "Test");


      List<Column> columnList = new ArrayList<>();

      Column idCol = Column.builder().type("Integer").name("id").build();

      Column userNameCol = Column.builder().type("String").name("userName").build();

      Column passwordCol = Column.builder().type("String").name("password").build();

      columnList.add(idCol);

      columnList.add(userNameCol);

      columnList.add(passwordCol);

      dataMap.put("colList", columnList);


      // 加载模版文件

      Template template = configuration.getTemplate("test.java.ftl");


      // 生成文件流

      File docFile = new File(CLASS_PATH + "/" + "Test.java");

      out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));


      // 输出到文件

      template.process(dataMap, out);

      System.out.println("Test.java 源码生成成功!");

    } catch (Exception e) {

      e.printStackTrace();

    } finally {

      try {

        if (null != out) {

          out.flush();

        }

      } catch (Exception e2) {

        e2.printStackTrace();

      }

    }

  }

}

我们执行FreemarkerTest的main方法,生成Test.java文件如下:

package com.freemark.demo;


public class Test {


    private Integer id;


    private String userName;


    private String password;



    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;

    }

}

四 总结

本篇对freemarker进行了深入一些的描述,并对上一篇的示例做了部分调整,使用了list、if等表达式、指令、插值这些freemarker的概念。

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Java编程语言,推荐大家关注一个微信公众号:Java圈子。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Java入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2023-03-2AoKIjPQ64014b4ad30a3.jpg

  • 发表于 2023-07-03 09:36
  • 阅读 ( 161 )
  • 分类:Java开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

1316 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章