Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey. How to generate json and xml output depending on url param

Here is a Jersey service:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {

  if (format.equals("json")) {...}

  return response;

}

I want to generate XML or JSON response back depending on url param "format".

My response instance is forming by jaxb2

I know I may get xml or json response back if on my Java client / functional test by using this code:

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_XML).get(String.class);

or

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_JSON).get(String.class);

But I need to do it depending on url param.

like image 631
ses Avatar asked Aug 02 '13 21:08

ses


3 Answers

You can set the media type of response entity directly via Response#ok (assuming you want to return HTTP 200 status) method

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {
    return Response
            // Set the status, entity and media type of the response.
            .ok(entity, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML)
            .build();
}

or by using Response.ResponseBuilder#header method

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response service(@QueryParam("format") String format) {
    return Response
            // Set the status and Put your entity here.
            .ok(entity)
            // Add the Content-Type header to tell Jersey which format it should marshall the entity into.
            .header(HttpHeaders.CONTENT_TYPE, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML)
            .build();
}
like image 120
Michal Gajdos Avatar answered Nov 03 '22 12:11

Michal Gajdos


This is not the proper way to do what you want. You shouldn't be using a query parameter to determine output format. You have declared that your resource method produces both XML and JSON, the standard compliant way is to let the client send a proper HTTP "Accept" header which declares what media types they are able to consume. If they send in "Accept: application/json", your JAX-RS implementation should choose to format your method's response as JSON, if the client sends "Accept: application/xml", it should automatically format your response as XML. If the client indicates they can accept either, your JAX-RS implementation is free to choose either and you shouldn't care. If the client indicates they can't accept either, your JAX-RS should send back an appropriate HTTP error code indicating they don't have a way to send back a proper response.

like image 23
user2456600 Avatar answered Nov 03 '22 14:11

user2456600


Here the complete example, the above answer is right. I also use the above approach but facing problem while working with List. I set the entity like this:

public Response getCoursesJSONOrXML(@QueryParam("type") String type){
    //Here we get list
    List<Course> entity= courseService.getAllCourses();
    Response response = Response
            .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
            .build();
    return response;
}

After that I'm facing this exception:

MessageBodyWriter not found for media type=application/json, type=class java.util.Arrays$ArrayList, genericType=class java.util.Arrays$ArrayList

After reading jersey document, I found the solution that we need to use GenericEntity for our course list. Here the example

@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Response getCoursesJSONOrXML(@QueryParam("type") String type){
    //Here we get list
    List<Course> list = courseService.getAllCourses();
    GenericEntity<List<Course>> entity = new GenericEntity<List<Course>>(list) {};
    Response response = Response
            .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
            .build();
    return response;
}
like image 1
Anshu Kumar Avatar answered Nov 03 '22 14:11

Anshu Kumar