Accept: */*
header which details which media types the client can accept. The server simply returns whatever we have coded for example @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
.
However I bet a number of you have seen something like this before:
http://www.example.com/documents/mydoc?format=docThe first example is not very subtle. It tells you the client wants a mydoc.doc by requesting a specific format. The second example is more subtle, and the end user (client) may not notice. I made it a "little" more obvious by changing it to .xml. However, most folks would have missed it if I used mydoc.doc. You would have assumed it was a MS Word document to start with. In actuality, the media type returned here is controlled by the file extension.
http://www.example.com/documents/mydoc.xml
Note: Updated the source code to include header based negotiation, but this is just mimicking server content negotiation.
In the attached Apache Maven project developed on NetBeans 7.1: jersey-content-negotiation.zip. I demonstrate how to do it.
The first example returns JSON by default, and other media formats as requested. If it does not understand the media type requested, it simply returns plain text.
On the second example which uses the media type extension, I return a 400 - Bad Request instead of plain text like the first example. This subtlety is based on the fact that the client is requesting a specific type based on extension. If you ask for .pdf and get .txt, the result may cause an unanticipated consequence so it is better to throw an exception.
The mixed media type returns are possible because of the
Response
being wrapped as demonstrated in a previous post: JAX-RS Tip of the Day: Use Response to wrap... Responses.ContentNegotiationResource.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright 2012 Blue Lotus Software, LLC.. * Copyright 2012 John Yeary <john.yeary@bluelotussoftware.com>. * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: ContentNegotiationResource.java,v 9b1064fb9d26 2012/01/12 18:14:54 jyeary $ */ package com.bluelotussoftware.example.jersey; import com.bluelotussoftware.example.jersey.misc.Widget; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; /** * Example resource class hosted at the URI path "/example" example * * @author John Yeary <john.yeary@bluelotussoftware.com> * @version 1.0 */ @Path( "/example" ) public class ContentNegotiationResource { private Widget widget; public ContentNegotiationResource() { widget = new Widget( "X" , "Y" ); } /** * Performs the client requested content negotiation based on format * requested. * * @param format may be one of "json", or "xml". The default is "json", and * an unknown value will be processed as {@link javax.ws.rs.core.MediaType.TEXT_PLAIN}. * @return a {@code Response} which wraps the entity which may be JSON, XML, * or text. */ @GET public Response getByFormat(@QueryParam(value = "format" ) @DefaultValue(value = "json" ) String format) { if ( "json" .equals(format)) { return Response.ok(widget, MediaType.APPLICATION_JSON).build(); } else if ( "xml" .equals(format)) { return Response.ok(widget, MediaType.APPLICATION_XML).build(); } else { return Response.ok( "widget : " + widget.toString(), MediaType.TEXT_PLAIN).build(); } } /** * Performs client requested content negotiation based on media type * requested based on extension. * * @param type media type extension which may be either ".json", or ".xml". * All other requested types will result in a {@link javax.ws.rs.WebApplicationException} * which has a {@link javax.ws.rs.core.Response.Status#BAD_REQUEST}. <p> * <b>Note: </b>There are no default types returned since this is specific * to the extension requested. </p> * @return a {@code Response} which wraps the entity which may be JSON, or * XML. */ @GET @Path(value = "widget.{type}" ) public Response getByType(@PathParam(value = "type" ) String type) { if ( "json" .equals(type)) { return Response.ok(widget, MediaType.APPLICATION_JSON).build(); } else if ( "xml" .equals(type)) { return Response.ok(widget, MediaType.APPLICATION_XML).build(); } else { /* * We will throw a WebApplcationException to indicate that we don't * accept the requested type. */ throw new WebApplicationException(Response.Status.BAD_REQUEST); } } } |
![]() |
Client Negotiation Examples |
0 comments :
Post a Comment