在 pom.xml 中引入 FreeMarker 核心依賴(版本可根據項目需求升級):
<!-- freemarker jar -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
在資源目錄下(如 src/main/webapp/freeMarker/)創建模板文件 testFreeMarker.flt:
您好${name},現在在測試FreeMarker功能
Web 環境下推薦使用 ServletContext 獲取模板路徑,避免硬編碼絕對路徑。採用單例模式管理 Configuration 實例。
package pers.kangxu.test.util;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* FreeMarker Web 環境工具類
* @author kangxu
*/
public class FreeMarkerUtil {
private static FreeMarkerUtil instance;
private Configuration config;
// 模板在 webapp 下的相對路徑
private String templatePath = "/freeMarker/";
private FreeMarkerUtil() {}
public static FreeMarkerUtil instance() {
if (instance == null) {
synchronized (FreeMarkerUtil.class) {
if (instance == null) instance = new FreeMarkerUtil();
}
}
return instance;
}
/**
* 惰性初始化 Configuration
*/
private void configInstance(HttpServletRequest request) {
if (this.config == null) {
synchronized (this) {
if (this.config == null) {
this.config = new Configuration();
// 關鍵:通過 ServletContext 加載模板,適應部署環境
this.config.setServletContextForTemplateLoading(
request.getSession().getServletContext(), templatePath);
}
}
}
}
/**
* 生成字符串
*/
public String geneFileStr(HttpServletRequest request, String templateFileName, Map<String, Object> propMap) {
configInstance(request);
StringWriter out = new StringWriter();
try {
Template tmp = this.config.getTemplate(templateFileName, "UTF-8");
tmp.setEncoding("UTF-8");
tmp.process(propMap, out);
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
return out.getBuffer().toString();
}
}
在 Spring MVC 控制器中注入 HttpServletRequest,調用工具類渲染模板並直接返回字符串(配合 @ResponseBody)。
package pers.kangxu.test.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import pers.kangxu.test.util.FreeMarkerUtil;
@Controller
@RequestMapping("/test-default")
public class TestController {
@RequestMapping(value = "test-freemarker", produces = "application/json; charset=utf-8")
@ResponseBody
public String testFreeMarker(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("name", "【我是名字】");
// 調用工具類生成內容
return FreeMarkerUtil.instance().geneFileStr(request, "testFreeMarker.flt", map);
}
}
訪問 /test-default/test-freemarker,瀏覽器將顯示渲染後的文本:
您好【我是名字】,現在在測試FreeMarker功能

setServletContextForTemplateLoading 替代文件系統路徑,解決打包部署(WAR/JAR)時的路徑問題。Configuration 對象線程安全且創建開銷大,必須單例複用。