Spring MVC中spring.ftl引发特殊字符双重转义问题求助
Spring 5.3.x + FreeMarker 双重转义问题解决方案
环境配置
- Spring版本:5.3.x
- FTL模板代码:
<#import "/spring.ftl" as spring/> <@spring.formInput path="${textInputName}" attributes='maxlength="1024" '/>
- FreeMarker参数配置(context.xml):
<property name="freemarkerSettings"> <props> <prop key="datetime_format">yyyy-MM-dd</prop> <prop key="url_escaping_charset">UTF-8</prop> </props> </property>
- 全局HTML转义配置(web.xml):
<context-param> <param-name>defaultHtmlEscape</param-name> <param-value>true</param-value> </context-param>
问题现象
输入框中输入值如"abc",页面刷新后被渲染为"abc",出现双重转义问题。
转义来源分析
- Spring绑定层转义:Spring的BindStatus类在处理表单绑定值时,会根据全局转义配置对值进行HTML转义。
- FreeMarker模板层转义:spring.ftl通过
#ftl output_format="HTML"开启了FreeMarker的自动转义功能,模板输出时会再次对内容进行HTML转义。
解决方案
无需关闭web.xml中的全局转义(避免降低安全性),推荐以下两种安全方案:
方案1:单个表单标签关闭Spring转义
在使用spring.formInput标签时,显式设置htmlEscape="false",关闭Spring层面的转义,依赖FreeMarker的自动转义保障安全:
<@spring.formInput path="${textInputName}" attributes='maxlength="1024"' htmlEscape="false"/>
方案2:全局配置关闭Spring表单标签转义
在context.xml的FreeMarker视图解析器中添加defaultHtmlEscape="false"配置,统一关闭所有Spring表单标签的转义逻辑:
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <!-- 原有配置(如前缀、后缀等) --> <property name="defaultHtmlEscape" value="false"/> </bean>
不推荐方案:修改FreeMarker输出格式
若强行保留Spring转义,可将spring.ftl中的#ftl output_format="HTML"改为TEXT,但会关闭FreeMarker自动转义,需手动处理所有转义,安全性大幅降低,不建议使用。
参考说明
根据Spring Framework官方issue的讨论,该问题属于Spring表单标签与FreeMarker自动转义的冲突场景,官方推荐依赖模板引擎的自动转义能力,关闭Spring层面的重复转义。
内容的提问来源于stack exchange,提问作者Arham Ranjha
相关产品推荐
相关产品推荐

