I am using org.springframework.oxm.jaxb.Jaxb2Marshaller to unmarshall my request xml. The unmarshalling fails because of the presence of '&' (ampersand) in the request even though the encoding is set in the prologue as
requestXML -
<?xml version="1.0" encoding="utf-8"?><createaccountrequest><username>Test&jsongg</username><userpassword>12345</userpassword></createaccountrequest>
The exception I get is as below
500 Internal Server Error org.springframework.http.converter.HttpMessageNotReadableException: Could not unmarshal to [class com.marketplace.system.customer.service.component.request.vo.AccountRequestVO]: null; nested exception is javax.xml.bind.UnmarshalException - with linked exception: [org.xml.sax.SAXParseException: The reference to entity "jsongg1h61" must end with the ';' delimiter.] at org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter.readFromSource(Jaxb2RootElementHttpMessageConverter.java:82) ~[spring-web-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter.readInternal(AbstractXmlHttpMessageConverter.java:61) ~[spring-web-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153) ~[spring-web-3.1.0.RELEASE.jar:3.1.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120) ~[spring-webmvc-3.1.0.RELEASE.jar:3.1.0.RELEASE]
Any pointers would be a great help.
Thanks in advance
The parser error is correct as
<username>Test&jsongg</username>
is not well formed XML. If you want an ampersand in the content of an element in XML then it needs to be escaped as &
.
The rules around XML character data - which characters can be used as-is, which need to be escaped (and how), and which are totally forbidden even in escaped form - are complex, and if you want to generate XML you should use an XML library to do so rather than trying to do it by hand. That said, you may be able to achieve what you want using CDATA. The following is well formed:
<username><![CDATA[Test&jsongg]]></username>
Blocks of text starting with <![CDATA[
and ending with ]]>
are treated as plain text by the parser, ampersands, less-than signs, etc. lose their special meaning. The thing to watch out for here is that CDATA sections don't nest, so if the value you're wrapping in CDATA contains the three character substring ]]>
then this will need to be "escaped" by replacing it with something like ]]]]><![CDATA[>
(the ]]
, then the end of the CDATA section and immediately start another, continuing with the >
).