JSF+PrimeFaces项目Ajax响应非法XML字符的处理方案问询
JSF/PrimeFaces Ajax响应XML解析错误:非法字符处理方案
问题描述
我们基于JSF和PrimeFaces开发Web应用时遇到一个异常场景:用户在<p:inputText>中粘贴U+FFFE这类字符并保存页面,普通页面渲染时浏览器仅显示字符无报错,但通过Ajax返回响应时,控制台会抛出XML Parsing Error: not well-formed错误。
核心原因
Ajax响应采用XML格式传输,而UTF-8中部分字符属于XML 1.0规范定义的无效字符(比如U+FFFE、U+FFFF,以及部分控制字符),XML解析器无法识别这类字符,直接导致解析失败。
已尝试的解决方案思路
目前提出两种处理方向,各有明显优缺点:
- 保存前校验输入
- 客户端JS校验:通用性强,但存在安全风险(可被恶意绕过)
- 直接替换非法字符:易引发用户误解(输入内容被静默修改,无明确提示)
- JSF自定义校验器:需逐个注册到
<p:inputText>组件,扩展性差,维护成本高
- 修改Ajax响应解析的JS代码:通过调整PrimeFaces/Mojarra的Ajax处理逻辑适配非法字符,但会增加维护成本,且可能影响版本兼容性
最小复现步骤
- 下载项目源码
- 执行构建命令:
mvn clean package - 将打包后的应用部署到WildFly 32.0.1.Final服务器
- 访问页面,在inputText中粘贴U+FFFE等非法字符并触发Ajax请求,即可在浏览器控制台看到解析错误
关键问题解答
如何在Java中快速检测字符串中的XML无效字符?
可以基于XML 1.0的规范,编写工具类实现检测或清理。示例代码如下:
import java.util.regex.Pattern; public class XmlCharValidator { // 匹配XML 1.0不允许的所有字符 private static final Pattern INVALID_XML_CHARS = Pattern.compile( "[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFFF]" ); // 检测字符串是否包含无效XML字符 public static boolean containsInvalidXmlChars(String input) { return INVALID_XML_CHARS.matcher(input).find(); } // 移除字符串中的无效XML字符 public static String removeInvalidXmlChars(String input) { return INVALID_XML_CHARS.matcher(input).replaceAll(""); } }
特殊场景说明
- U+0002这类控制字符会被JSF writer自动移除,这是Mojarra的默认处理逻辑
- U+FFFE即使在校验阶段抛出异常,仍会在渲染阶段显示,该现象怀疑与Mojarra的#4516 Bug相关(该Bug涉及字符校验与渲染阶段的处理不一致问题)
内容的提问来源于stack exchange,提问作者László Tóth
相关产品推荐
相关产品推荐

