I have spring set up to use: Jaxb2RootElementHttpMessageConverter as the message converter to convert an object to xml. In my rest service when a response is generated it does not adhere to the JAXB annotations i have provided on the model classes.
:
BaseResponse:
@XmlRootElement(name="response")
@XmlSeeAlso({AddMemberResponse.class,UpdateMemberResponse.class})
public abstract class BaseResponse {
private int status;
private String message;
private String confirmationCode;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(int httpInternalError) {
this.status = httpInternalError;
}
public String getConfirmationCode() {
return confirmationCode;
}
public void setConfirmationCode(String confirmationCode) {
this.confirmationCode = confirmationCode;
}
}
AddMemberResponse:
@XmlRootElement(name = "response")
@XmlAccessorType(XmlAccessType.FIELD)
public class AddMemberResponse extends BaseResponse {
private Member member;
public AddMemberResponse() {
super();
}
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
}
In one point in my code, I have to save the xml to the database, so I have to manually convert this to a String to be saved later, and for this I use the JaxbMarshaller class and this works fine:
/**
* Converts object to xml using jaxb marshaller
*/
private String objectToXML(Object graph) throws IOException {
String finalstring = null;
try {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.company.ws");
Map<String, Object> map = new HashMap<String, Object>();
map.put("jaxb.formatted.output", true);
marshaller.setMarshallerProperties(map);
// create a StringWriter for the output
StringWriter outWriter = new StringWriter();
StreamResult result = new StreamResult(outWriter);
marshaller.marshal(graph, result);
StringBuffer sb = outWriter.getBuffer();
finalstring = sb.toString();
log.debug(finalstring);
} catch(Exception e) {
e.printStackTrace();
}
return finalstring;
}
It stores this in the database with the jaxbmarshaller like this:
<response>
<status>500</status>
</response>
But it returns this as the response in POSTMAN:
<AddMemberResponse>
<status>500</status>
<message/>
<confirmationCode>UVHRWLHB6UMQ</confirmationCode>
<member/>
</AddMemberResponse>
The 500 comes from it not being able to connect to an external service for data, so it is not relevant, it should still return the initial way as described.
app-servlet.xml with the message converters configured:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Enables the Spring4 @Controller -->
<mvc:annotation-driven />
<!-- To convert JSON to Object and vice versa -->
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
<!-- To convert XML to Object and vice versa -->
<bean id="xmlMessageConverter" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter">
</bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
<ref bean="xmlMessageConverter"/>
</list>
</property>
</bean>
<!-- Dozer configuration -->
<bean id="beanMapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>dozerMapping.xml</value>
</list>
</property>
</bean>
<context:component-scan base-package="com.company" />
</beans>
Update1:
as "application/xml" using [org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@3f767117]
is showing in the logs, so it isn't using the right converter when marshaling it for the response.
I had to remove a jackson dependency on the classpath:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-xml-provider</artifactId>
<version>2.4.3</version>
</dependency>
MappingJackson2XmlHttpMessageConverter@3f767117 takes precedence over the jaxb converter, if it is on the classpath, hence the marshaling was being done by that converter and not my jaxb one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With