So I got json working where someone can post an object in json form, and my controller method maps that to the actual java object. My spring config xml looks like:
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jsonMessageConverter"/>
</util:list>
</property>
</bean>
And a test controller method that works is like:
@ResponseBody
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String create(@RequestBody User user, HttpServletRequest request, HttpServletResponse response) {
return user.getName();
}
Now if I want the exact same method to work with xml also, is this possible?
Which message converter do I use?
BTW, if I want to keep certain properties of private, how can I do that so it works for both json and xml?
e.g. say I have a password property, I don't want anyone being able to post this information.
I'm using Spring 3.1 and this is how I'm doing.
In dispatcher-servelet.xml
<bean id="jacksonObjectMapper" class="com.parth.web.CustomJacksonMapper"/>
<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="aliases">
<props>
<prop key="event">com.parth.model.Event</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.parth.model.Event</value>
</list>
</property>
</bean>
<oxm:jaxb2-marshaller id="jaxb2Marshaller">
<oxm:class-to-be-bound name="com.parth.model.Event"/>
</oxm:jaxb2-marshaller>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter" p:marshaller-ref="xstreamMarshaller" p:unmarshaller-ref="xstreamMarshaller"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" p:objectMapper-ref="jacksonObjectMapper" />
</mvc:message-converters>
</mvc:annotation-driven>
And in Controller,
@RequestMapping(value="/",method= RequestMethod.GET)
@ResponseBody
public List<Event> getAllEvents(@RequestParam("userId") String userId, HttpServletResponse response){
return eventService.getAll(userId);
}
Now, when you make HTTP request from client make sure you set Accept
header either with appliction/json or application/xml
.
As far as omitting fields, you cans use annotations @JsonIgnore
(for Jackson) and/or @XStreamOmitField
(for XStream).
Make sure you have Jackson and XStream jars in your class path.
You can pick any implementation in the org.springframework.http.converter.xml package as long as you consider the respective requirements.
You can tell the a method what types it will consume through the consumes attribute of the RequestMapping annotation.
I.E. from the Spring Documentation:
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
Note: this is a comma-separated list, so you can also have application/xml as well.
Important to note as well, this will only accept those content-types, which gives you a
bit of safety, but might lead to unexpected results. What I mean is, if you send /pets
text/plain, the method will not be called.
To do the correct binding, inspect the content type sent through the HttpServletRequest
and unmarshal depending on what type you are dealing with.
(Answering this even though its very old in case someone comes across this in a site search) -
You can use ContentNegotiationViewResolver http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-multiple-representations
I am using this one to handle both:
@RequestMapping(value = "/{id}",
method = RequestMethod.GET,
headers ={"Accept=application/json,application/xml"},
produces={"application/json", "application/xml"})