Spring REST Web Service and Content Negotiation
Join the DZone community and get the full member experience.
Join For FreeThere is couple of ways to enable content negotiation in spring REST web service.
- Using header values in @RequestMapping
annotation.
We can map a request based on its Accept header value in the @RequestMapping . Also multiple values can be specified separated with comma.
@RequestMapping(value="/order/{id}", method = RequestMethod.GET, headers = "Accept=application/json","application/xml") public Customer findOrderById(@PathVariable String id) { Order order; try { order = orderService.getOrderDetails(id); } catch (OrderNotFoundException e) { system.out.println("Order not found in the system"); } return order; }
I want to mention here that , instead of @PathVariable annotation we can use @RequestParam annotation to map values in request url. We can explicitly define the parameters to be mapped using the param field.
@RequestMapping(value="/order/", , params = "id", method = RequestMethod.GET, headers = "Accept=application/json,application/xml") public Customer findOrderById(@RequestParam("id") long id) { Order order; try { order = orderService.getOrderDetails(id); } catch (OrderNotFoundException e) { system.out.println("Order not found in the system"); } return order; }
- Using spring content negotiation manager.
When the controller returns the value, content negotiation manager gets the control and check for three things in the request.
1. Is there an extension (eg .xml/.json) with the request?
2. Is there a parameter (eg ?format=json) with the request?
3. Is there a accept header specified in the request?
Content negotiation manager always checks for strategy in this order, path extension, parameter and Accept header. In spring rest web service by default content negotiation manager will work with extension. We don’t need to make any configuration for this. But using extensions are not standard in REST web service.
In order to enable custom content negotiation logic, you need to define a content negotiation manager in the diapatcher servlet. Please see below the bean defined.
<!-- To switch on content negotiation strategies --> <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="favorPathExtension" value="false"/> <property name="favorParameter" value="true"/> <property name="parameterName" value="formatType"/> <property name="mediaTypes"> <map> <entry key="json" value="application/json"></entry> <entry key="xml" value="application/xml"></entry> </map> </property> <property name="ignoreAcceptHeader" value="false"/> </bean>
For this content negotiation manager we defined the three strategies we defined earlier. We can set those values to true or false. Here we are disabling the strategies 1 and 3 and enabling strategy 2. We can explicitly provide the parameter name(eg : formatType) and the media types that can be used.
I hope this will help you to properly define a content negotiation strategy for your REST web service.
Opinions expressed by DZone contributors are their own.
Comments