FreeMarker语法

Posted Androider_Zxg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FreeMarker语法相关的知识,希望对你有一定的参考价值。

FreeMarker语法

概述

最近做公司一个需求,代码生成模板,编写用于生成Java Bean的ftl文件。在此记录下使用Freemarker的常用语法

FreeMarker Java使用

  1. 实例化FreeMarker配置类
Configuration conf = new Configuration();
  1. 设置配置类路径,也就是将会从该路径下读取模板文件
conf.setDirectoryForTemplateLoading(new File(dir));
  1. 读取模板文件
Template template = conf.getTemplate("freemarker.html");
  1. 定义数据模型
    将模型放入一个Map中,可以放入对象、基本类型、List、,Map等
 Map<String,Object> root = new HashMap<String,Object>();
        Person p = new Person();
        p.setId("111");
        p.setName("哈哈哈");
        root.put("person", p);
        root.put("world", "世界你好");
        //遍历List
        List<String> persons = new ArrayList<String>();
        persons.add("阿灵罗");
        persons.add("罗零");
        persons.add("灵罗");
        root.put("persons",persons);
  1. 定义输出文本的文件
Writer out = new FileWriter(new File(dir+"hello.html"));
  1. 调用模板process方法,传入数据模型及目标文件,生成文本
template.process(root, out);
    out.flush();
    out.close();
  1. 在freemarker.html中访问放入map的数据结构,如:
<#list persons as p>
Id:$p.id
Name:$p.name
</#list>

FreeMarker语法

这里我们根据业务需求,自定义数据结构。在ftl文件中解析数据结构,以这个过程为串联,学习FreeMarker语法

数据结构

NetInterface:用于描述网络请求接口

public class NetInterface 
	// 请求名称
	private String interfaceId;
	// 请求功能描述
	private String caption;
	// 备注信息
	private String comment;
	// 请求相对路径
	private String path = "";
	// 自定义请求地址
	private String customFullPath = "";
	// 请求类型(Post 和 Get,会覆盖 service 中配置)
	private String request_mode;
	// 成功标识
	private String succFlag;
	// 错误提示信息
	private String errorMsg;
	// 请求 model
	private SCRequestModel requestModel = new SCRequestModel();
	// 返回数据 model
	private SCResponseModel responseModel = new SCResponseModel();

	public SCInterface(String methodName, SCRequestModel request, SCResponseModel response) 
		this.interfaceId = methodName;
		this.requestModel = request;
		this.responseModel = response;
	

RequestModel:描述请求参数

public class RequestModel 
	private String modelName = "";
	// 请求参数
	private List<SCParam> fields = new ArrayList<SCParam>();
	private Boolean hasCustomModel = false;
	//嵌套的子Model
	private List<RequestModel> subModels = new ArrayList<SCResponseModel>();
	

ResponseModel:描述返回数据参数

public class ResponseModel 
	private String modelName = "";
	// 请求参数
	private List<SCParam> fields = new ArrayList<SCParam>();
	private Boolean hasCustomModel = false;
	//嵌套的子Model
	private List<ResponseModel> subModels = new ArrayList<SCResponseModel>();

Param:描述一个参数

public class SCParam 
    //枚举数据类型
	public enum ParamEnum 
	    //系统类型 String等
		ParamSystem(0),
		//系统List 如List<String>
		ParamArray_sys(1),
		//自定义对象类型
		ParamObject(2),
		//List 泛型为自定义对象
		ParamArray_object(3);
		
		private int mState = 0;
	    private ParamEnum(int value) 
	        mState = value;
	    
	    public int getState() 
	    	return mState;
	    
	
	// 字段名称
	private String paramName;
	// 参数类型
	private ParamEnum paramType;
	// 系统字段类型
	private String sysType;
	// 备注信息
	private String caption;
	// 扩展数据类型(当不为默认类型时,使用此字符存储)
	private List<SCParam> extendParam;
	

这里,假设我们已经有了一个List,并把它放入map中,如下:

List<NetInterface> netInterfaces = DataProvider.getInterfaces();
Map<String,Object> root = new HashMap();
root.put("interfaces",netInterfaces)
root.put("Id","abcd")
template.process(root, writer);

这样,我们在ftl文件中就能通过key值interfaces来访问List。下面我们介绍一下常用的语法

注释

<#-- 注释内容 -->

访问值

<#-- result:abcd -->
$Id

List相关

循环list

<#list interfaces as interface>
    <#-- 访问interface -->
    path:$interface.path
    interfaceId:$interface.interfaceId
</#list>

list size判断

<#list interfaces as interface>
    <#-- 注意一定要加括号,否则报错 -->
    <#if (interface.requestModel.fields?size == 0)>
    <#-- gt代表大于 -->
    <#elseif (interface.requestModel.fields?size gt 0)>
    <#-- lt代表小于 -->
    <#elseif (interface.requestModel.fields?size lt 0)>
    </#if>
</#list>

下标判断

<#list interfaces as interface>
    <#-- 是否是最后一个 -->
    <#if interface_has_next>
        非最后一个
    <#else>最后一个元素
    </#if>
    <#-- 是否为第一个-->
    <#if (interface_index == 0)></#if>
    <#if >
</#list>

if条件判断

<#-- 判空-->
<#if interface.request_mode??>
    <#if interface.request_mode == "post">
    <#-- 输出内容 -->
    <#elseif interface.request_mode == "post">
    <#-- 输出内容 -->
    <#elseif interface.request_mode == "post">
    <#-- 输出内容 -->
    <#elseif interface.request_mode == "post">
    <#-- 输出内容 -->
    <#else>
    error
    </#if>
</#if>

首字母大小写

<#-- 首字母大写 -->
$param.paramName?cap_first
<#-- 首字母小写 -->
$param.paramName?uncap_first

宏定义

可以理解为自定义方法,我们看一个解析字段名的宏

<#-- 解析字段 -->
<#macro parserField target>
<#list target as param>
    // $param.caption
<#if param.paramType.getState() == 0>
<#if param.sysType == "string">
    public String $param.paramName?uncap_first;
<#elseif param.sysType == "int32">
    public int $param.paramName?uncap_first;
<#elseif param.sysType == "boolean">
    public boolean $param.paramName?uncap_first;
<#elseif param.sysType == "double">
    public double $param.paramName?uncap_first;
<#elseif param.sysType == "int64">
    public long $param.paramName?uncap_first;
<#elseif param.sysType == "float">
    public float $param.paramName;
<#else>
    parserClass error type state:$paramType.getState(),type:$param.sysType
</#if>
<#elseif param.paramType.getState() == 2>
    public $param.sysType?trim?cap_firstObject $param.sysType?uncap_firstObject;
<#elseif param.paramType.getState() == 3>
    public List<$param.sysType?trim?cap_firstObject> $param.sysType?uncap_firstObjectList = new ArrayList();
<#elseif param.paramType.getState() == 1>
<#if param.paramName == "list">
    public List<<@parserType target = param.sysType/>> list = new ArrayList();
<#else>
    public List<<@parserType target = param.sysType/>>  $param.paramNameList = new ArrayList();
</#if>
</#if>
</#list>
</#macro>

大家可以结合文章上面阐述的数据结构来看,就难理解了
调用方式

<@parserField target=interface.responseModel.fields/>

判空

正确写法

<#if responseModel.subModels??>

错误写法

<#if responseModel?.subModels>

暂时用到的语法就这些

后记

Freemarker比较难调试,是因为暂时没找到IDE提示错误,全部要肉眼来看,靠freemarker的提示来找线索。所以写的时候一定要注意语法规范,错一点就会报错。如果有好的IDE,请安利给我

以上是关于FreeMarker语法的主要内容,如果未能解决你的问题,请参考以下文章

FreeMarker语法2

freemarker的基本语法

FreeMarker语法

Freemarker的基本语法

NetSuite 高级 PDF 模板 - Freemarker 语法

FreeMarker的基础语法使用 && 心得和技巧