Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST 3 to Support XML and JSON

If we develop REST using Spring MVC, it will support XML and JSON data. I have wrote ContentNegotiationViewResorver in my spring config bean app-servlet.xml

<bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
        p:order="1">
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <property name="marshaller">
                        <bean class="org.springframework.oxm.xstream.XStreamMarshaller"
                            p:autodetectAnnotations="true" />
                    </property>
                </bean>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            </list>
        </property>
    </bean>

And my spring REST Controller is:

@Controller
@RequestMapping("/rest/customers")
class CustomerRestController {

protected Log log = LogFactory.getLog(CustomerRestController.class);

@RequestMapping(method = POST)
@ResponseStatus(CREATED)
public void createCustomer(@RequestBody Customer customer,
        HttpServletResponse response) {

    log.info(">>>" + customer.getName());
    response.setHeader("Location", String.format("/rest/customers/%s",
            customer.getNumber()));
}


@RequestMapping(value = "/{id}", method = GET)
@ResponseBody
public Customer showCustomer(@PathVariable String id) {
    Customer c = new Customer("0001", "teddy", "bean");
    return c;
}


@RequestMapping(value = "/{id}", method = PUT)
@ResponseStatus(OK)
public void updateCustomer(@RequestBody Customer customer) {
    log.info("customer: " + customer.getName());
}

I set @XStreamAlias("customer") annotation in my customer domain class. But when I try access http://localhost:8080/rest/customers/teddy.xml it always response JSON data.

I set @XmlRootElement(name="customer") annotation in my customer domain class. But when I try access http://localhost:8080/rest/customers/teddy.json it always response XML data.

Is there some thing wrong ?

like image 683
Adi Sembiring Avatar asked Jan 16 '11 02:01

Adi Sembiring


People also ask

How do I accept both JSON and XML in Spring Boot?

Implementing XML Representation for Spring Boot Services Restart your application. Send a request to http://localhost:8080/students/10001 with Accept header as 'application/xml'. Cool! Your application now supports both XML and JSON representations of the student resource.

Does the RESTful method support JSON or XML or both format?

The same resource may return either XML or JSON depending upon the request, but it shouldn't return both at the same time.

Does RESTful API support XML?

Data types that REST API can return are as follows: JSON (JavaScript Object Notation) XML. HTML.

Does Spring Boot support JSON?

Spring Boot provides integration with three JSON mapping libraries: Gson. Jackson. JSON-B.


2 Answers

I think "xml" content type should be mapped to "text/xml" not to "application/xml". Also, to force content type resolvers based on extension, you can try to set the "favorPathExtension" property of "ContentNegotiatingViewResolver" to true(though it should have been true by default!)

EDIT: I have now added a working sample at this GIT location - git://github.com/bijukunjummen/mvc-samples.git, if you bring up the endpoint, using mvn tomcat:run, the json is served at http://localhost:8080/mvc-samples/rest/customers/teddy.json and xml at http://localhost:8080/mvc-samples/rest/customers/teddy.xml. This uses JAXB2 not XStream, as I am familiar with JAXB. One thing I noticed was that when my JAXB annotations were not correct in Customer class, Spring was serving out JSON and not XML the way you saw it(You can replicate it by removing the XMLRootElement annotation from Customer class), once I fixed up my annotations, I got back XML as expected. So it could be that there is something wrong with your XStream configuration.

EDIT 2: You are right!! I did not notice, once I got back xml, I assumed that json is working now. I see the problem, in AnnotationMethodHandlerAdapter, the handling for @ResponseBody is a little strange, it completely ignores the ViewResolvers, and uses the registered MessageConverters instead completely bypassing the ContentNegotiatingViewResolver, one workaround for now is to use @ModelAttribute annotation for response, instead of @ResponseBody, this way the view Resolvers are getting called. Try now using the project at [email protected]:bijukunjummen/mvc-samples.git and see if it works for you. This could be a Spring bug, you may try and bring it up in the Spring forum and see what they recommend.

like image 135
Biju Kunjummen Avatar answered Oct 05 '22 23:10

Biju Kunjummen


What Accept headers are sent to your server? Make sure the content type you would like to request is in this list.

like image 44
Jochen Bedersdorfer Avatar answered Oct 05 '22 23:10

Jochen Bedersdorfer