【问题标题】:XStream double underscore - handling in Java Spring Batch Application ContextXStream 双下划线 - 在 Java Spring Batch 应用程序上下文中处理
【发布时间】: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-staxeventitemwriterXStream 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


    【解决方案1】:

    显然我做错了。以下似乎有效:

    <beans:bean id="myMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <beans:property name="nameCoder">
            <beans:bean class="com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder">   
                <beans:constructor-arg index="0" value="_-"/>
                <beans:constructor-arg index="1" value="_"/>
            </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>
    

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      • 2016-02-23
      • 1970-01-01
      • 2012-07-18
      • 1970-01-01
      相关资源
      最近更新 更多