More philosophical content negotiation

In a previous blog entry i showed a way to support platonic and distinct URIs (with a redirection twist). An alternative way to do this (motivated by a comment from Patrick Mueller) is to use a URI template variable that captures the suffix corresponding to the media type, do some initialization work in a constructor and then use one HTTP method, as follows:

@UriTemplate("/helloworld{media}")
public class HelloWorldResource {
    static final MediaType XML = new MediaType("application/xml");
    static final MediaType JSON = new MediaType("application/json");
    static final List<MediaType> acceptableList = Arrays.asList(XML, JSON);
   
    @HttpContext
    HttpContextAccess context;

    @HttpContext
    UriInfo uriInfo;
   
    MediaType contentType;
   
    public HelloWorldResource(@UriParam("media") String media) {
        if (media.equals(".xml")) {
            contentType = XML;
        } else if (media.equals(".json")) {
            contentType = JSON;
        } else if (media.length() == 0) {
            contentType = null;
        } else {
            throw new NotFoundException();           
        }
    }
   
    @HttpMethod
    @ProduceMime({"application/xml", "application/json"})
    public Response get() {
        if (contentType == XML) {
            contentType = context.getHttpRequestContext().
                getAcceptableMediaType(Arrays.asList(XML));           
        } else if (contentType == JSON) {
            contentType = context.getHttpRequestContext().
                getAcceptableMediaType(Arrays.asList(JSON));           
        } else if (contentType == null) {
            contentType = context.getHttpRequestContext().
                getAcceptableMediaType(acceptableList);           
        }

        if (contentType == null) {
            throw new WebApplicationException(Response.Builder.
                    noContent().status(406).build());
        }
       
        return Response.Builder.representation(contentType.toString(),
                contentType).build();
    }

(I am cheating a bit by not returning actual XML or JSON content as i am too lazy to put some JAXB code together.)  

In this example the platonic URI returns a representation instead of redirecting. To be correct it is necessary to check what is acceptable for distinct URIs and return a Not Acceptable (406) response, for example, if the distinct URI is "/helloworld.xml" but the requested acceptable content is "application/json".

There is still a lot of boiler plate in the application code but the way this code is structured indicates that it should be possible to push such things into the runtime.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

sandoz

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
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
   
       
Today