You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FreeMarker模板处理中转义Unicode符号?

解决FreeMarker 2.3.28中?eval解析含en-dash/em-dash的JSON报错问题

这个问题我之前也碰到过,本质是**?eval的设计初衷不是用来解析JSON**,而是解析FreeMarker表达式——这就是为什么特殊破折号会触发词法错误的核心原因。

错误原因拆解

当你用?eval处理JSON字符串时,FreeMarker会把整个字符串当作FTL语法来解析。en-dash(–)和em-dash(—)这类符号不在FTL的合法语法规则里,词法分析器会把它们当成未知的语法标记,直接抛出lexical error: encountered "u" (117)这类错误。而版权(©)、商标(®)符号只是普通Unicode字符,FTL会把它们当作字符串内容处理,所以不会出问题。

解决方案(按推荐程度排序)

1. 在Java层提前解析JSON(最稳妥)

既然你的需求是JSON转XML,完全可以先在Java代码里把JSON解析成Java对象(比如Map<String, Object>或自定义POJO),再把这个对象传入FreeMarker模板。模板直接访问对象属性,根本不需要用?eval。

举个Jackson解析的示例:

// 假设你的JSON字符串是jsonStr
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> data = objectMapper.readValue(
    jsonStr, 
    new TypeReference<Map<String, Object>>() {}
);

// 把解析后的对象传入模板
Template template = configuration.getTemplate("your-template.ftl");
template.process(
    data, 
    new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)
);

之后模板里直接用${text}就能访问{"text": "Hello – World"}里的内容,所有Unicode符号都能正常输出,完全避开?eval的坑。

2. 给模板注册自定义JSON解析方法(适配2.3.28)

因为FreeMarker 2.3.28还没内置?eval_json(这个特性在2.3.29才加入),如果必须在模板里处理JSON字符串,可以自己在Java层注册一个用专业JSON库(Jackson/Gson)解析的方法。

步骤1:注册自定义方法到FreeMarker配置
Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
cfg.setDefaultEncoding("UTF-8");

// 注册parseJson方法,用于模板内解析JSON
cfg.setSharedVariable("parseJson", new TemplateMethodModelEx() {
    @Override
    public Object exec(List arguments) throws TemplateModelException {
        if (arguments.size() != 1) {
            throw new TemplateModelException("parseJson需要1个参数:JSON字符串");
        }
        String jsonStr = ((SimpleScalar) arguments.get(0)).getAsString();
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonStr, Object.class);
        } catch (IOException e) {
            throw new TemplateModelException("JSON解析失败:" + e.getMessage(), e);
        }
    }
});
步骤2:在模板中调用自定义方法
<#assign jsonData = parseJson(jsonString)>
<!-- 正常访问解析后的属性 -->
<text>${jsonData.text}</text>

内容的提问来源于stack exchange,提问作者boredDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:42