java - Accepting / returning XML/JSON request and response - Spring MVC -
i need write rest service accepts xml/json input (post method) , xml/json output (based on input format). have tried below approach achieve doesn't helped out.endpoint method accepts both xml/json while responding gives either json or xml based on order specified in @requestmapping -produces.any appreciated.
my endpoint method:
@requestmapping(value = "/getxmljson", method = requestmethod.post,produces={"application/json","application/xml"}, consumes={"application/json", "application/xml"}) public @responsebody student processxmljsonrequest(@requestbody student student) throws exception { system.out.println("*************inside controller"); return student; }
pojo class: student.java
import java.io.serializable; import java.util.arraylist; import javax.xml.bind.annotation.xmlelement; import javax.xml.bind.annotation.xmlrootelement; import javax.xml.bind.annotation.xmltype; import com.fasterxml.jackson.annotation.jsonignore; import com.fasterxml.jackson.annotation.jsonpropertyorder; @xmlrootelement(name = "student") @xmltype(proporder = {"id", "name", "graduationtime", "courses"}) @jsonpropertyorder({"id", "name", "graduationtime", "courses"}) public class student implements serializable { private static final long serialversionuid = 1l; private int id; private string name; private string graduationtime; private arraylist<course> courses = new arraylist<course>(); @xmlelement public int getid() { return id; } @xmlelement public string getname() { return name; } @xmlelement public string getgraduationtime() { return graduationtime; } @xmlelement public arraylist<course> getcourses() { return courses; } public void setid(int value) { this.id = value; } public void setname(string value) { this.name = value; } public void setgraduationtime(string value) { this.graduationtime = value; } public void setcourses(arraylist<course> value) { this.courses = value; } @jsonignore public string tostring() { return this.name + " - " + graduationtime == null? "unknown" : graduationtime.tostring(); } public student() {} public student(int id, string name, string graduationtime) { this.id = id; this.name = name; this.graduationtime = graduationtime; } }
pojo class: course.java
import java.io.serializable; import javax.xml.bind.annotation.xmlelement; import javax.xml.bind.annotation.xmlrootelement; import javax.xml.bind.annotation.xmltype; import com.fasterxml.jackson.annotation.jsonpropertyorder; @xmlrootelement(name = "course") @xmltype(proporder = {"coursename", "score"}) @jsonpropertyorder({"coursename", "score"}) public class course implements serializable { private static final long serialversionuid = 1l; private string coursename; private integer score; public @xmlelement string getcoursename() { return coursename; } public @xmlelement integer getscore() { return score; } public void setcoursename(string value) { coursename = value; } public void setscore(integer value) { score = value; } public course() {} public course(string coursename, integer score) { this.coursename = coursename; this.score = score; } }
spring-config.xml
<?xml version="1.0" encoding="utf-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:sws="http://www.springframework.org/schema/web-services" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:util="http://www.springframework.org/schema/util" xsi:schemalocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd"> <!-- dispatcherservlet context: defines servlet's request-processing infrastructure --> <!-- enables spring mvc @controller programming model --> <annotation-driven /> <!-- handles http requests /resources/** efficiently serving static resources in ${webapproot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- configure plugin json request , response in method handler --> <beans:bean class="org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter"> <beans:property name="messageconverters"> <beans:list> <beans:ref bean="jsonmessageconverter" /> <beans:ref bean="xmlmessageconverter" /> </beans:list> </beans:property> </beans:bean> <!-- configure bean convert json pojo , vice versa --> <beans:bean id="jsonmessageconverter" class="org.springframework.http.converter.json.mappingjackson2httpmessageconverter"> </beans:bean> <beans:bean id="xmlmessageconverter" class="org.springframework.http.converter.xml.jaxb2rootelementhttpmessageconverter"> </beans:bean> <beans:bean id="resttemplate" class="org.springframework.web.client.resttemplate"> </beans:bean> <beans:bean id="objectmapper" class="com.fasterxml.jackson.databind.objectmapper" /> <context:component-scan base-package="com.test" /> </beans:beans>
json input:
{ "id":2014, "name":"test", "graduationtime":"09/05/2014", "courses":[ { "coursename":"math", "score":150 }, { "coursename":"che", "score":150 } ] }
xml input:
<?xml version="1.0" encoding="utf-8" ?> <student> <id>2014</id> <name>test</name> <graduationtime>09/05/2014</graduationtime> <courses> <coursename>math</coursename> <score>150</score> </courses> <courses> <coursename>che</coursename> <score>150</score> </courses> </student>
the best practice handling different data formats same controller let framework work of figuring out marshalling , unmarshalling mechanisms.
step 1: use minimal controller configuration
@requestmapping(value = "/getxmljson", method = requestmethod.post) @responsebody public student processxmljsonrequest(@requestbody student student) { return student; }
there no need specify consumes
, produces
here. example, consider may want same method handle other formats in future such google protocol buffers, edi, etc. keeping controllers free of consumes
, produces
let add data formats through global configuration instead of having modify controller code.
step 2: use
contentnegotiatingviewresolver
instead ofrequestmappinghandleradapter
<bean class="org.springframework.web.servlet.view.contentnegotiatingviewresolver"> <property name="defaultviews"> <list> <bean class="org.springframework.web.servlet.view.json.mappingjackson2jsonview"/> </list> </property> </bean>
let view resolver decide how read incoming data , how write back.
step 3: use
accepts
,content-type
http headers
hitting controller correct http header values force contentnegotiatingviewresolver
marshal , unmarshal data automatically using appropriate data representations.
if want exchange data in json format, set both headers application/json
. if want xml instead, set both application/xml
.
if not want use http headers (which ideally should), can add .json
or .xml
url , contentnegotiatingviewresolver
rest.
you can check out my sample app created using code snippets works fine json , xml.
Comments
Post a Comment