返回

FreeMarker

发布时间:2023-02-14 15:38:23 417
# less# java# 数据# 货币# 工具

字符串空值处理:
freemarker中变量必须赋值,否则报错

  1. ​!​​ : 指定缺失变量的默认值,不设置是空字符串

输出name的值:${name}。如果name为null,就会报错。

输出name的值:${name!}。如果name为null,就不会报错,什么也没输出。(重点)

输出name的值:${name!"默认值"}。如果name为null,就输出”默认值”字符串。(重点)

输出name的值:${name!100}。如果name为null,就输出100。

输出user.name的值:${(user.name)!"默认值”},如果user或name为null,就输出默认值。(重点)

输出user.name的值:${user.name!"默认值”},如果user为null会报错,如果name为null,就输出默认值。

使用default内建函数来处理:${user.name?default('vakin')}  (较繁琐)

  1. ​??​​: 判断变量是否存在,如果变量存在返回true,否则返回false

product.color??将只测试color是否为null


      (product.color)??将测试product和color是否存在null

 

  1. freemarker中??和?的区别

??是判断对象是否为空,例如:<#if object??>object对象不为空(即object存在)</#if>

?后面要加内建函数名,例如:<#if object?exists>object对象不为空(即object存在)</#if>

<#if str??>${str?string}</#if><#--将str以字符串形式显示-->

 

 

 

 

 

 

 

 

简介

FreeMarker标签使用 
一、FreeMarker模板文件主要有4个部分组成
1、文本,直接输出的部分
2、注释,即<#--...-->格式不会输出
3、插值(Interpolation):即${..}或者#{..}格式的部分,将使用数据模型中的部分替代输出
4FTL指令:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出。

FTL指令规则
FreeMarker有三种FTL标签,这和HTML的标签是完全类似的
开始标签:<#directivename parameters>
结束标签:</#directivename>
空标签: <#directivename parameters />
实际上,使用标签时前面的#符号也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改为@符号



直接指定的值,可以是字符串,布尔,数值,集合,map

插值规则
FreeMarker的插值有如下两种类型
1、通用插值:${expr}
2、数字格式化插值:#{expr}或者#{expr;format}

通用插值,有可以分为四种情况
a、插值结果为字符串值:直接输出表达式结果,字符串中可以使用转义字符,如果有大量的特殊字符,,可以在引号前面加一个字母r,则字符串将按照原样输出,不转义
b、插值结果为数字值:根据默认格式(#setting 指令设置)将表达式结果转换成文本输出。可以使用内建的字符串函数格式单个插值,例如
<#setting number_format = "currency" />
<#assign price = 42 />
${price}
${price?string}

数字格式化插值
数字格式化插值可采用#{expr;format}的形式来格式化数字,其中format可以是:
mX:小数部分最小X
MX:小数部分最大X
例如:
<#assign x = 2.582 />
<#assign y =4 />
#{x;M2};
#{y;M2};
#{x;m1};
#{y;m1};
#{x;m1M2};
#{y:m1M2};

数字格式
${x?string.number}
货币格式
${x?string.currency}
百分比格式
${x?string.percent}
保留两位小数格式
${x?string["0.##"]}

c、输出值为日期值:根据默认格式(由 #setting 指令设置)将表达式结果转换成文本输出,可以使用内建的字符串函数格式化单个插值,例如
<#assign lastUpdated = "2009-01-07 15:05"?datetime("yyyy-MM-dd HH:mm") />
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")};
${lastUpdated?string("EEE,MMM d,yy")};
${lastUpdated?string("EEEE,MMMM dd,yyyy,hh:mm:ss a '('zzz')'")};
${lastUpdated?string.short};
${lastUpdated?string.long};
${lastUpdated?String.full};
d、插值结果为布尔值,布尔值不能直接输出,使用 myBool?string('yes', 'no') 或者myBool?string或者myBool?c
<#assign foo=true />
${foo?string("是foo","非foo")}

 

 

FreeMarker 常用指令

if

if指令
分支控制语句
语法格式如下
<#if condition>
....
<#elseif condition2>
...
<#elseif condition3>
...
<#else>
...
</#if>

switch

switchcasedefaultbreak指令
<#switch value>
<#case refValue>
...
<#bread>
<#case refValue>
...
<#bread>
<#default>
...
</#switch>
虽然FreeMarker提供了switch指令,但它并不推荐使用switch指令来控制也输出,而是推荐使用FreeMarkerif..elseif..else 指令来替代它。

list

listbreak指令
list指令时一个典型的迭代输出指令,用于迭代输出数据模型中的集合。list指令的语法格式如下:
<#list sequence as item>
...
</#list>
除此之外,迭代集合对象时,还包括两个特殊的循环变量:
aitem_index:当前变量的索引值。
bitem_has_next:是否存在下一个对象
也可以使用<#break>指令跳出迭代

遍历list
<#list ["星期一","星期二","星期三","星期四","星期五"] as x>
${x_index +1}.${x} <#if x_has_next>,</#if>
<#if x = "星期四"><#break></#if>
</#list>

<#--拼接list-->
<#list ["星期一","星期二"]+["星期三","星期四","星期五"] as x>
${x_index +1}.${x} <#if x_has_next>,</#if>
<#if x = "星期四"><#break></#if>
</#list>

<#--直接获取-->
<div>${list[0]}</div>

遍历map
<#assign info={"username":"cj","password":"123"}>
<#list info?keys as key>
<div>${key}---${info[key]}</div>
</#list>
<#list info?values as value>
<div>${value}</div>
</#list>

<#--拼接map-->
<#list (info+{"birthday":birthday})?keys as key>
<div>${key} ---</div>
</#list>

 

include

include 指令
include指令的作用类似于JSP的包含指令,用于包含指定页,include指令的语法格式如下
<#include filename [options]
在上面的语法格式中,两个参数的解释如下
afilename:该参数指定被包含的模板文件
boptions:该参数可以省略,指定包含时的选项,包含encodingparse两个选项,encoding指定包含页面时所使用的解码集,而parse指定被
包含是否作为FTL文件来解析。如果省略了parse选项值,则该选项值默认是true

 

import

import指令
该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中,import 指令的语法格式如下
<#import path as mapObject>
在上面的语法格式中,path指定要被导入的模板文件,而mapObject是一个Map对象名,通过这行代码,将导致path模板中的所有变量都被放置
mapObject
<#import "/lib/common.ftl" as com>

noparse

noparse指令指定FreeMarker不处理该指令里包含的内容,该指令的语法格式如下:
<#noparse>
...
</#noparse>

escape

escapenoescape指令

assign

assign指令
它用于为该模板页面创建或替换一个顶层变量
map:
<#assign score = {“语文”:78,”数学”:83,”Java”:89} >
list:
<#assign score = [“语文”,”数学”,”Java”] >

setting

setting指令
该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:
<#setting name = value>
name 的取值范围包括如下几个
locale :该选项指定该模板所用的国家/语言选项
number_format:该选项指定格式化输出数字的格式
boolean_format:该选项指定两个布尔值的语法格式,默认值是"true、false"
date_format,time_format,datetime_format:该选项指定格式化输出日期的格式
time_zone: 设置格式化输出日期时所使用的时区

其他

macronestedreturn指令

 

函数

内建函数

字符串操作

<#-- 直接输出${msg1} - ${msg2}<br>
${msg1?string} -${msg2?string} <br>
<#-- 1. 截取字符串(左闭右开)?substring(start,end) --)
{msg2?substring(1,4)} <br>
<div>${str[0]}</div>
<div>${str[1..3]}</div>
<#-- 2.首字母小写输出 ?uncap first -->
${msg1?uncap_first} <br>
<#-- 3.首字母大写输出 ?cap first -->
${msg2?cap_first}<br>
<#-- 4.字母转小写输出 ?lower case -->
${msg1?lower case} <br>
<#-- 5.字母转大写输出 ?upper case -->
${msg1?upper case} <br>
<#-- 6.获取字符串长度 ?length -->
${msg1?length} <br>
<#-- 7.是否以指定字符开头(boolean类型) ?starts with("xx")?string --)
${msg1?starts with("H")?string} <br>
<#-- 8.是否以指定字符结尾(boolean类型) ?ends with("xx")?string -->
${msg1?ends_with("h")?string} <br>
<#-- 9.获取指定字符的索引 ?index of("xxx")
${msg1?index of("e")} <br>
<#-- 10.去除字符串前后空格 ?trim -->
${msg1?trim?length} <br>
<#-- 11.替换指定字符串 ?replace("xx","xxx")-->
${msg1?replace("o","a")}<br>
<#-- 12 拼接字符串-->
<div>${"hello "+name}</div>
<div>${"hello ${name}"}</div>
<#-- 13 对字符串进行HTML编码-->
${msg1?html)}

集合

size: 获得序列中元素的数目
${list?size}

数字值

int 取得数字的整数部分
${10.5?int}

 

运算符

比较运算符
表达式中支持的比较运算符有如下几个
a、=(或者==):判断两个值是否相等.
b!=:判断两个值是否不相等
c、 >(或者gt):判断坐标值是否大于右边值
d、 >=(或者gte):判断坐标值是否大于等于右边值
e、 <(或者lt):判断左边值是否小于右边值
f、 <=(或者lte):判断左边值是否小于等于右边值

逻辑运算符
逻辑运算符有如下几个
a、逻辑与:&&
b、逻辑或:||
c、逻辑非:!
逻辑运算符只能作用于布尔值,否则将产生错误。

 

freemarker-2.3.29

 

/**
* Copyright © 1998-2016, Glodon Inc. All Rights Reserved.
*/
package com.glodon.gboat3.base.tools.util.template;

import com.glodon.gboat3.base.tools.GboatAppContext;
import freemarker.cache.StringTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.URLTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.StringWriter;
import java.io.File;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.Map;


/**
* freemarker模板工具
*
* @author zhaic
*
*/
public class FreemarkerUtil {
private FreemarkerUtil(){}
/**
* 用freeMark模板生成内容
*
* @param path 模板文件相对路径 eg. /template,此路径和content,static 文件夹平级
* @param tplFileName 模板文件名称
* @param classLoader 当前bundle 的类加载器
* @return
*/
public static String createContent(final String path, final String tplFileName, Map<String, Object> data,
final ClassLoader classLoader) {
// 模板路径
String result = "";

// 加载freemarker模板文件
try {
URLTemplateLoader loader = new URLTemplateLoader() {
@Override
protected URL getURL(String name) {
return classLoader.getResource(path + "/" + tplFileName);
}
};

Configuration cfg = initConfig(loader);
// 获取指定模板文件
Template template = cfg.getTemplate(tplFileName);
// 定义输入文件,默认生成在工程根目录
StringWriter writer = new StringWriter();
template.process(data, writer);
writer.flush();
writer.close();
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 用freeMark模板生成文件
*
* @param path 模板文件相对路径 eg. /template,此路径和content,static 文件夹平级
* @param tplFileName 模板文件名称
* @param fileName 文件名+扩展名
* @param classLoader 当前bundle 的类加载器
* @return
*/
public static String createFile(final String path, final String tplFileName, Map<String, Object> data,
String fileName,final ClassLoader classLoader) {
// 模板路径
String result = "";


// 加载freemarker模板文件
try {
URLTemplateLoader loader = new URLTemplateLoader() {
@Override
protected URL getURL(String name) {
return classLoader.getResource(path + "/" + tplFileName);
}
};
Configuration cfg = initConfig(loader);
// 定义并设置数据
// 获取指定模板文件
Template template = cfg.getTemplate(tplFileName);
String fileBasePath = GboatAppContext.getWebRootPath() + "freemarker";
File file = new File(fileBasePath);
// 判断文件夹是否存在,如果不存在则创建文件夹
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
// 定义输入文件,默认生成在工程根目录freemarker
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileBasePath+"/"+fileName), "UTF-8"));
template.process(data, writer);
writer.flush();
writer.close();
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 填充模板内容
* @param templateContent 模板内容
* @param data 参数
* @return
*/
public static String createContent(String templateContent,Map<String, Object> data){
String result = "";
try {
StringTemplateLoader stringLoader = new StringTemplateLoader();
stringLoader.putTemplate("myTemplate",templateContent);
Configuration cfg = initConfig(stringLoader);

// 获取模板
Template template = cfg.getTemplate("myTemplate", "utf-8");
// 定义输入文件,默认生成在工程根目录
StringWriter writer = new StringWriter();
template.process(data, writer);
writer.flush();
writer.close();
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}


/**
* 初始化配置对象
*
* @return
*/
private static Configuration initConfig(TemplateLoader templateLoader) {
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
cfg.setDefaultEncoding("UTF-8");
cfg.setClassicCompatible(true);
cfg.setTemplateLoader(templateLoader);
return cfg;
}
}

 

 

 

 

 

 

 

 

 

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
kotlin flow介绍(1) 2023-02-14 15:06:45