jackson-dataformat-xml - 自定义实体导致的 Jackson XML“未声明的一般实体”
问题描述
我正在反序列化一个大型 XML 文件(不是我的),它包含定义为的自定义实体:
<!ENTITY math "mathematics">
和以这种方式使用的元素:
<field>&math;</field>
当我尝试通过以下方式反序列化它时:
XmlMapper xmlMapper = new XmlMapper();
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
return xmlMapper.readValue(classloader.getResourceAsStream("file.xml"), MyClass.class);
我收到此错误:com.fasterxml.jackson.databind.JsonMappingException:未声明的一般实体“数学”
我认为这可能是一种防止 Xml 外部实体注入的安全措施。
- 有没有办法将这些自定义实体标记为有效?像为他们创建一个 Enum 之类的?
- 如果没有,是否有一个标志可以将它们解析为字符串?
更新:我基本上可以通过对文本文件进行查找替换来解决这个问题。这是一个非常丑陋的解决方案,如果有人有更好的主意,我会全力以赴。:)
解决方案
我知道这可能有点晚了,但以防其他人陷入同样的问题:
您必须将自定义 XMLResolver 设置为 XMLInputFactory 的属性:
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.ctc.wstx.api.WstxInputProperties;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamException;
var xmlMapper = new XmlMapper();
xmlMapper.getFactory().getXMLInputFactory().setProperty(
WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER,
new XMLResolver() {
@Override
public Object resolveEntity(String publicId, String systemId, String baseUri, String ns) throws XMLStreamException {
// replace the entity with a string of your choice, e.g.
switch (ns) {
case "nbsp":
return " ";
default:
return "";
}
// some useful tool is org.apache.commons.text.StringEscapeUtils
// e.g.
// return StringEscapeUtils.escapeXml10(StringEscapeUtils.unescapeHtml4('&' + ns + ';'));
}
}
);
// then xmlMapper.readValue....
推荐阅读
- javascript - Angular,如何进行连续的、依赖的http get请求
- asp.net-mvc - 在查询 linq 中使用 Mapper.Map
- javascript - 如何将表单数据添加到 Laravel Echo 请求?
- javascript - 如何将嵌入式链接发布到 Draft.js 富文本编辑器中?
- php - json_decode() 返回 NULL
- flask - Mongoengine EmbeddedDocumentListField // 我只能访问get方法
- python - 如何编写迭代函数
- python-3.x - Pandas 风格的 applymap 使用 lambda 函数突出显示重复项
- eclipse - 如何将现有 UI 添加到 SWT Designer (WindowBuilder)
- css - 为什么元素选择器会用 !important 覆盖类选择器?