FreeMarker是一个功能强大的Java模板引擎,广泛应用于生成动态内容,如HTML、XML和其他文本格式。本文将介绍FreeMarker的基本使用方法,并提供一个更丰富的XML模板示例,以及模板标签和标识的含义。
1. 引入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
2. 编写生成XML的方法
以下是一个实现IXMLGeneratorService接口的服务类示例,该类负责加载FreeMarker模板并生成XML文件。
@Service("InitXMLGeneratorServiceImpl")
@Slf4j
public class InitXMLGeneratorServiceImpl implements IXMLGeneratorService {
@Value("${project.path:config.cfg}")
private String path;
/**
* 模板加载方法
*
* @param templateContent 模板内容字符串
* @return 加载的模板
*/
@Override
public Template templateBuild(String templateContent) {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setClassForTemplateLoading(InitXMLGeneratorServiceImpl.class, "/");
StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
stringTemplateLoader.putTemplate("config.ftl", templateContent);
cfg.setTemplateLoader(stringTemplateLoader);
try {
return cfg.getTemplate("config.ftl");
} catch (IOException e) {
log.error("加载配置XML模板出现异常:{}", e.getMessage());
return null;
}
}
/**
* 生成XML
*
* @param template 模板对象
* @param data 数据模型
* @param path 文件保存路径
* @param fileName 文件名
* @return 生成的XML内容及文件信息
*/
@Override
public JSONObject createXMLAndGetAllPath(Template template, JSONObject data, String path, String fileName) {
JSONObject jsonObject = new JSONObject();
try {
StringWriter writer = new StringWriter();
template.process(data, writer);
String xml = writer.toString();
File file = new File(path + "/" + fileName);
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(xml);
bw.flush();
jsonObject.set("xmlContent", xml);
jsonObject.set("file", file);
return jsonObject;
} catch (Exception e) {
log.error("写出XML模板出现异常:{}", e.getMessage());
return null;
}
} catch (IOException | TemplateException e) {
log.error("生成XML模板出现异常:{}", e.getMessage());
return null;
}
}
}
3. 定义更丰富的XML模板
以下是一个更丰富的XML模板示例,适用于生成配置文件:
<!-- config.ftl -->
<configuration>
<#if itemList?has_content>
<itemList>
<#list itemList as item>
<item name="${item.name}" value="${item.value}" status="${item.status}">
<description>${item.description}</description>
<#if item.attributes?has_content>
<attributes>
<#list item.attributes as attribute>
<attribute name="${attribute.name}" value="${attribute.value}"/>
</#list>
</attributes>
</#if>
</item>
</#list>
</itemList>
</#if>
<version value="${version}"/>
<date>${date}</date>
<author>${author}</author>
<comments>
<#if comments?has_content>
<#list comments as comment>
<comment>${comment}</comment>
</#list>
</#if>
</comments>
</configuration>
模板说明
<item>: 表示单个配置项,包含名称、值和状态等信息。
<attributes>: 可选元素,包含配置项的属性列表。
<author>: 添加了作者信息,标识配置文件的创建者。
<comments>: 包含可选的注释信息,用于提供额外的上下文。
模板标签与标识含义
4.1 模板标签
<#if>:条件判断标签,用于检查变量是否存在或有内容。
用法示例:<#if condition> ... </#if>
<#list>:循环标签,用于遍历集合。
用法示例:<#list collection as item> ... </#list>
${}:变量插值,用于输出数据模型中的值。
用法示例:${variable}
?has_content:检查变量是否有内容,返回布尔值。
用法示例:variable?has_content
?size:获取集合的大小。
用法示例:collection?size
4.2 模板标签属性参数说明
name:配置项的名称,标识该项的唯一性。
示例:<item name="${item.name}">
value:配置项的值,表示该项的具体内容。
示例:<item value="${item.value}">
status:配置项的状态,表示该项的启用或禁用状态。
示例:<item status="${item.status}">
description:对配置项的描述,提供更多上下文信息。
示例:<description>${item.description}</description>
attributes:可选属性,包含额外的配置信息。
示例:<attribute name="${attribute.name}" value="${attribute.value}"/>
DOM4J生成XML方式
优点
编程方式:通过Java代码直接构建XML,适合简单结构的生成。
类型安全:直接使用Java对象,避免了模板解析的潜在错误。
灵活性:适合动态生成XML,不依赖外部模板文件。
示例代码
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.dom4j.DocumentHelper;
import java.io.FileOutputStream;
public class XMLGenerator {
public void generateXML() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement("configuration");
Element itemList = root.addElement("itemList");
for (Item item : itemListData) {
Element itemElement = itemList.addElement("item");
itemElement.addAttribute("name", item.getName());
itemElement.addAttribute("value", item.getValue());
itemElement.addAttribute("status", item.getStatus());
itemElement.addElement("description").setText(item.getDescription());
if (item.getAttributes() != null) {
Element attributes = itemElement.addElement("attributes");
for (Attribute attribute : item.getAttributes()) {
Element attributeElement = attributes.addElement("attribute");
attributeElement.addAttribute("name", attribute.getName());
attributeElement.addAttribute("value", attribute.getValue());
}
}
}
root.addElement("version").addAttribute("value", "1.0");
root.addElement("date").setText("2024-08-23");
root.addElement("author").setText("Your Name");
try (FileOutputStream fileOutputStream = new FileOutputStream("output.xml")) {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(fileOutputStream, format);
writer.write(document);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
对比总结
生成方式:FreeMarker基于模板文件,适合动态内容;DOM4J通过Java代码构建,适合简单结构。
可读性:FreeMarker模板结构清晰,易于维护;DOM4J代码较长,结构不如模板清晰。
灵活性:FreeMarker支持复杂逻辑和条件判断;DOM4J动态生成XML,但不支持复杂条件。
类型安全:FreeMarker依赖于模板解析,可能出现运行时错误;DOM4J直接使用Java对象,类型安全。
适用场景:FreeMarker适合需要频繁修改的动态内容生成;DOM4J适合简单、固定结构的XML生成。