XStream double underscore - handling in Java Spring Batch Application Context -
i using xstream oxm (java objects xml). namecoder uses underscore default escape character (more info below) , since have ext_data xml tag, being written ext__data.
xstream maps java class names , field names xml tags or attributes. unfortunately mapping cannot 1:1, since characters used identifiers in java invalid in xml names. therefore xstream uses anxmlfriendlynamecoder replace these characters replacement. default namecoder uses underscore escape character , has therefore escape underscore also. may provide different configured instance of xmlfriendlynamecoder or complete different implementation thenonamecoder prevent name coding @ all. responsibility ensure, resulting names valid xml. (http://x-stream.github.io/faq.html)
i have attempted providing different configured instance of xmlfriendlynamecoder (using various implementations of hierarchicalstreamdriver) using complete different implementation of nonamecoder. although app runs successfully, results remain unchanged. using xstream 1.4.8.
there plenty of examples of how use suggested workaround (here couple, http://forum.spring.io/forum/spring-projects/batch/74500-getting-double-underscores-in-xml-when-using-staxeventitemwriter, xstream , underscores) confident various attempts have been set correctly (but overlooking something). here recent configuration:
<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>
i'm not sure issue seems spring isn't picking configuration reason. digging through org.springframework.oxm.xstream.xstreammarshaller looks streamdriver used within marshaloutputstream (and marshalwriter, called within marshaloutputstream) perhaps have configured in such way custom implementation ignored , default streamdriver used...
@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 given graph 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); } { try { streamwriter.flush(); } catch (exception ex) { logger.debug("could not flush hierarchicalstreamwriter", ex); } } }
i realize question seems unique , narrow in scope responses may shed light on larger question of how configuring streamdriver within application context (in spring batch app).
note- using spring 4 , java 8.
thanks
edit: i've tried using following configuration:
<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>
apparently going wrong way. below seems working:
<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>
Comments
Post a Comment