I managed to work around the issue by using a Custom Converter in XStream.
I created an XmlEncodedStringConverter that used the apache commons lang
StringEscapeUtils.escapeXml() and unescapeXml():
public class XmlEncodedStringConverter implements Converter {
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
String value = (String)source;
writer.setValue(StringEscapeUtils.escapeXml(value));
}
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
String escapedValue = reader.getValue();
return StringEscapeUtils.unescapeXml(escapedValue);
}
public boolean canConvert(Class type) {
return String.class.isAssignableFrom(type);
}
}
Then when I publish a message to my queues - I use Xstream like this:
XStream xstream = new XStream()
xstream.registerCustomConverter(new XmlEncodedStringConverter());
template.sendBody("direct:start", xstream.toXml(myObject));
In my Camel Routes - I did this:
public void configure() {
XStream xstream = new XStream();
xstream.registerConverter(new XmlEncodedStringConverter());
from("direct:start")
.unmarshal(new XStreamDataFormat(xstream))
.process(myProcessor)
.marshal(new XStreamDataFormat(xstream))
.convertBodyTo(String.class)
.to("mock:result");
}
Doing this - all of my issues/exceptions disappeared. Not ideal - but it
should work until the issue can be resolved in Camel 2.2.0 and we can
upgrade these processes to that version.
Is there an easier way of doing that? ie: Is there a way I can create the
xstream instance that the route will use so that i can do:
unmarshal().xstream() - and register the xstream instance globally for the
whole camel context? Or is this the only way to set the instance of xstream
used by the unmarshalling processor?
Thanks!
Jonathan
willem.jiang wrote:
>
> It's a bug of XStream DataFormat.
> I created a JIRA[1] for it.
>
> [1] https://issues.apache.org/activemq/browse/CAMEL-2407
>
> Willem
>
> jonathanq wrote:
>> I should also mention - this is Camel 2.0.0
>>
>>
>> jonathanq wrote:
>>> I am trying to unmarshal an xml message from JMS that was originally
>>> marshaled using Xstream.
>>>
>>> When I create the message I am doing this:
>>>
>>> XStream xstream = new XStream(new DomDriver("ISO-8859-1"));
>>> template.sendBody(xstream.toXml(myObject));
>>>
>>>
>>> On the consuming process I have this in my route:
>>>
>>> from(endpoint).unmarshal().xstream().process(myProcessor);
>>>
>>> The XStream unmarshal always fails due to non-UTF-8 characters. And the
>>> stacktrace shows that it was a UTF8 reader that failed.
>>>
>>> So my question is - is there a way to initialize XStream to use a
>>> specific
>>> DomDriver (with an encoding). Or any way to specify the encoding to use
>>> by default?
>>>
>>> I tried adding this to the route (right after the from, and before the
>>> unmarshal):
>>> .setProperty(Exchange.CONTENT_ENCODING, constant("iso-8859-1"))
>>>
>>> Didn't make a difference.
>>>
>>>
>>> Here is the stack trace:
>>>
>>> Caused by: com.thoughtworks.xstream.io.StreamException: : Invalid UTF-8
>>> start byte 0xa0 (at char #638, byte #-1)
>>> at
>>> com.thoughtworks.xstream.io.xml.StaxReader.pullNextEvent(StaxReader.java:64)
>>> at
>>> com.thoughtworks.xstream.io.xml.AbstractPullReader.readRealEvent(AbstractPullReader.java:137)
>>> at
>>> com.thoughtworks.xstream.io.xml.AbstractPullReader.readEvent(AbstractPullReader.java:130)
>>> at
>>> com.thoughtworks.xstream.io.xml.AbstractPullReader.move(AbstractPullReader.java:109)
>>> at
>>> com.thoughtworks.xstream.io.xml.AbstractPullReader.moveDown(AbstractPullReader.java:94)
>>> at
>>> com.thoughtworks.xstream.io.xml.StaxReader.<init>(StaxReader.java:44)
>>> at
>>> com.thoughtworks.xstream.io.xml.StaxReader.<init>(StaxReader.java:34)
>>> at
>>> org.apache.camel.dataformat.xstream.XStreamDataFormat.createHierarchicalStreamReader(XStreamDataFormat.java:83)
>>> at
>>> org.apache.camel.dataformat.xstream.AbstractXStreamWrapper.unmarshal(AbstractXStreamWrapper.java:88)
>>> at
>>> org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:51)
>>> at
>>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:61)
>>> at
>>> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:186)
>>> at
>>> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:155)
>>> at
>>> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:88)
>>> at
>>> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49)
>>> at
>>> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:148)
>>> at org.apache.camel.processor.Pipeline.process(Pipeline.java:74)
>>> at
>>> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:54)
>>> at
>>> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48)
>>> at
>>> org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:45)
>>> at
>>> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:170)
>>> at
>>> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:156)
>>> at
>>> org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:141)
>>> at
>>> org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:155)
>>> at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:93)
>>> at
>>> org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:97)
>>> at
>>> org.apache.camel.impl.DefaultProducerTemplate.sendBodyAndHeader(DefaultProducerTemplate.java:136)
>>> ... 29 more
>>> Caused by: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte
>>> 0xa0
>>> (at char #638, byte #-1)
>>> at com.ctc.wstx.sr.StreamScanner.throwFromIOE(StreamScanner.java:708)
>>> at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1086)
>>> at
>>> com.thoughtworks.xstream.io.xml.StaxReader.pullNextEvent(StaxReader.java:49)
>>> ... 55 more
>>> Caused by: java.io.CharConversionException: Invalid UTF-8 start byte
>>> 0xa0
>>> (at char #638, byte #-1)
>>> at com.ctc.wstx.io.UTF8Reader.reportInvalidInitial(UTF8Reader.java:302)
>>> at com.ctc.wstx.io.UTF8Reader.read(UTF8Reader.java:188)
>>> at com.ctc.wstx.io.ReaderSource.readInto(ReaderSource.java:84)
>>> at
>>> com.ctc.wstx.io.BranchingReaderSource.readInto(BranchingReaderSource.java:57)
>>> at com.ctc.wstx.sr.StreamScanner.loadMore(StreamScanner.java:992)
>>> at com.ctc.wstx.sr.StreamScanner.getNext(StreamScanner.java:763)
>>> at
>>> com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:1995)
>>> at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1069)
>>>
>>
>
>
>
--
View this message in context:
http://old.nabble.com/XStream-and-forcing-ISO-8859-1-Encoding-tp27328336p27343260.html
Sent from the Camel - Users mailing list archive at Nabble.com.