【发布时间】:2015-06-20 12:43:33
【问题描述】:
我正在使用 XStream for oxm(Java Objects to xml)。 NameCoder 使用下划线作为默认转义字符(下面有更多信息),因为我将 ext_data 作为 xml 标记,所以它被写为 ext__data。
XStream 将 Java 类名和字段名映射到 XML 标记或属性。不幸的是,这种映射不能是 1:1,因为在 Java 中用于标识符的某些字符在 XML 名称中是无效的。因此 XStream 使用一个 XmlFriendlyNameCoder 来替换这些字符。默认情况下,此 NameCoder 使用下划线作为转义字符,因此也必须转义下划线本身。您可以提供 XmlFriendlyNameCoder 的不同配置实例或完全不同的实现,例如 theNoNameCoder,以完全防止名称编码。但是,您有责任确保生成的名称对 XML 有效。 (http://x-stream.github.io/faq.html)
我尝试提供不同的 XMLFriendlyNameCoder 配置实例(使用 HierarchicalStreamDriver 的各种实现)以及使用完全不同的 NoNameCoder 实现。虽然应用程序运行成功,但结果保持不变。我正在使用 XStream 1.4.8。
有很多关于如何使用建议的解决方法的示例(这里有几个,http://forum.spring.io/forum/spring-projects/batch/74500-getting-double-underscores-in-xml-when-using-staxeventitemwriter,XStream and underscores)所以我相当有信心我的各种尝试都已正确设置(但我可能会忽略一些东西) .这是我最近的配置:
<beans:bean id="myMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<beans:property name="streamDriver">
<beans:bean class="com.thoughtworks.xstream.io.xml.Xpp3Driver">
<beans:constructor-arg>
<beans:bean class="com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder">
<beans:constructor-arg index="0" value="DDD"/>
<beans:constructor-arg index="1" value="_"/>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</beans:property>
<beans:property name="fieldAliases">
<util:map id="aliases">
<beans:entry key="com.billup.beans.Data.extData" value="ext_data"/>
</util:map>
</beans:property>
</beans:bean>
我不太确定,但问题似乎是 Spring 出于某种原因没有采用此配置。通过 org.springframework.oxm.xstream.XStreamMarshaller 进行挖掘,看起来 streamDriver 仅在 marshalOutputStream (和 marshalWriter,在 marshalOutputStream 中调用)中使用,所以也许我将其配置为忽略自定义实现并使用默认 streamDriver ...
@Override
protected void marshalXmlEventWriter(Object graph, XMLEventWriter eventWriter) throws XmlMappingException {
ContentHandler contentHandler = StaxUtils.createContentHandler(eventWriter);
marshalSaxHandlers(graph, contentHandler, null);
}
@Override
protected void marshalXmlStreamWriter(Object graph, XMLStreamWriter streamWriter) throws XmlMappingException {
try {
marshal(graph, new StaxWriter(new QNameMap(), streamWriter));
}
catch (XMLStreamException ex) {
throw convertXStreamException(ex, true);
}
}
@Override
protected void marshalOutputStream(Object graph, OutputStream outputStream) throws XmlMappingException, IOException {
if (this.streamDriver != null) {
marshal(graph, this.streamDriver.createWriter(outputStream));
}
else {
marshalWriter(graph, new OutputStreamWriter(outputStream, this.encoding));
}
}
@Override
protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
SaxWriter saxWriter = new SaxWriter();
saxWriter.setContentHandler(contentHandler);
marshal(graph, saxWriter);
}
@Override
protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
if (this.streamDriver != null) {
marshal(graph, this.streamDriver.createWriter(writer));
}
else {
marshal(graph, new CompactWriter(writer));
}
}
/**
* Marshals the given graph to the given XStream HierarchicalStreamWriter.
* Converts exceptions using {@link #convertXStreamException}.
*/
private void marshal(Object graph, HierarchicalStreamWriter streamWriter) {
try {
getXStream().marshal(graph, streamWriter);
}
catch (Exception ex) {
throw convertXStreamException(ex, true);
}
finally {
try {
streamWriter.flush();
}
catch (Exception ex) {
logger.debug("Could not flush HierarchicalStreamWriter", ex);
}
}
}
我意识到这个问题似乎独特且范围狭窄,但回答可能会阐明如何在应用程序上下文中正确配置 streamDriver 的更大问题(在 Spring Batch 应用程序中)。
注意-我使用的是 Spring 4 和 Java 8。
谢谢
编辑: 我也尝试过使用以下配置:
<beans:bean id="myMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<beans:property name="streamDriver">
<beans:bean class="com.thoughtworks.xstream.io.xml.DomDriver">
<beans:constructor-arg value="UTF-8"/>
<beans:constructor-arg>
<beans:bean class="com.thoughtworks.xstream.io.naming.NoNameCoder"/>
</beans:constructor-arg>
</beans:bean>
</beans:property>
<beans:property name="fieldAliases">
<util:map id="aliases">
<beans:entry key="com.billup.beans.Data.extData" value="ext_data"/>
</util:map>
</beans:property>
</beans:bean>
【问题讨论】:
标签: java spring spring-batch xstream double-underscore