项目开发需求将xstream从1.4.17升级到1.4.18,升级后遇到了序列化问题,描述如下:
om.thoughtworks.xstream.security.ForbiddenClassException: com.jd.jcloud.wms.pickingplan.dto.eclp.SoOrderCancelReceipt
at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:133) ~[xstream-1.4.18.jar:1.4.18]
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) ~[xstream-1.4.18.jar:1.4.18]
问题还原:
pom.xml
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.18</version>
</dependency>
代码
public static void main(String[] args) {
XStream xStream = new XStream();
String xmlStr = "<receipt>\n" +
"<receiptNo>1234567</receiptNo>\n" +
"<distributeNo></distributeNo>\n" +
"<warehouseNo>123</warehouseNo>\n" +
"<erpWarehouseNo></erpWarehouseNo>\n" +
"<receiptType>123</receiptType>\n" +
"<source>123</source>\n" +
"<partnerNo>123</partnerNo>\n" +
"<clpsWarehouseNo>123</clpsWarehouseNo>\n" +
"</receipt>";
xStream.alias("receipt", SoOrderCancelReceipt.class);
xStream.ignoreUnknownElements();
SoOrderCancelReceipt soOrderReceipt = (SoOrderCancelReceipt) xStream.fromXML(xmlStr);
System.out.println(JSON.toJSONString(soOrderReceipt));
}
结果:
Exception in thread "main" com.thoughtworks.xstream.security.ForbiddenClassException: SoOrderCancelReceipt
at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:133)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1391)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1376)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1261)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1252)
at Test3.main(Test3.java:35)
处理方案:解析之前,在前面添加以下两行代码
Class<?>[] classes = new Class[] { SoOrderCancelReceipt.class};
xStream.allowTypes(classes);
完整代码如下:
public static void main(String[] args) {
XStream xStream = new XStream();
String xmlStr = "<receipt>\n" +
"<receiptNo>123456</receiptNo>\n" +
"<distributeNo></distributeNo>\n" +
"<warehouseNo>123</warehouseNo>\n" +
"<erpWarehouseNo></erpWarehouseNo>\n" +
"<receiptType>123</receiptType>\n" +
"<source>123</source>\n" +
"<partnerNo>123</partnerNo>\n" +
"<clpsWarehouseNo>123</clpsWarehouseNo>\n" +
"</receipt>";
xStream.alias("receipt", SoOrderCancelReceipt.class);
xStream.ignoreUnknownElements();
Class<?>[] classes = new Class[] { SoOrderCancelReceipt.class};
xStream.allowTypes(classes);
SoOrderCancelReceipt soOrderReceipt = (SoOrderCancelReceipt) xStream.fromXML(xmlStr);
System.out.println(JSON.toJSONString(soOrderReceipt));
}
执行结果:
{"clpsWarehouseNo":"123","distributeNo":"","partnerNo":"123","receiptNo":"123456","receiptType":"123","source":123,"warehouseNo":"123"}
Process finished with exit code 0