Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Annotating resource to produce JSON, but return "text/plain" in response header

I am currently implementing a web API

  • Spring
  • Jersey
  • com.thetransactioncompany.cors http://software.dzhuvinov.com/cors-filter.html

The output (if any) will be JSON, so all my classes are annotated with the expected media type.

@Produces(MediaType.APPLICATION_JSON)
public class CustomerResource {
    ...
}

that way my classes are automatically transformed to json.

BUT...

Due to microsoft, their IE only support CORS, if the request/response type is text/plain http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

4. Only text/plain is supported for the request's Content-Type header

so I need to force my application to respond with text/plain in the header but still projecting my classes to json output. I know that the CORS classes I added is setting that header, but somehow that is overwritten again by my annotation, even if I add another filter by my own.

like image 561
MatthiasLaug Avatar asked Nov 20 '12 12:11

MatthiasLaug


1 Answers

Hum, the link you are pointing says that it is true for REQUESTS only. So you can accept only text plain but are free to produce what ever you want.

EDIT Try registering a custom responsefilter with code similar to that (maybe you already did it?):

@Provider
public class HeaderRewriteFilter implements ContainerResponseFilter {
   @Override
   public ContainerResponse filter(ContainerRequest request, ContainerResponse response)  {
     response.setResponse(Response
                .fromResponse(response.getResponse()).header(HttpHeaders.CONTENT_TYPE, "text/plain").build());
             return response;
  }
}

However check the result to ensure it is ok if the response already contains this header. Otherwise you can try to modify the current response, but I am not sure you can as it might be an immutable object. And by the way it looks less clean to me :)

List<Object> contentTypes = response.getHttpHeaders().get(HttpHeaders.CONTENT_TYPE);
contentTypes.clear();
contentTypes.add("text/plain");

Also for doing json<>java databiding you can check Genson library http://code.google.com/p/genson/, it integrates well with Jersey. Just drop the jar in the classpath and run!

EDIT 2 OK then you must do it in the other way, use produces "text/plain" and define a json bodywriter for for that type. Downside is that you will be able to produce only json. With Genson you could do it that way:

@Provider
@Produces({ MediaType.TEXT_PLAIN })
public class PlainTextJsonConverter extends GensonJsonConverter {
    public GensonJsonConverter() {
       super();
    }

    public GensonJsonConverter(@javax.ws.rs.core.Context Providers providers) {
       super(providers);
    }
}
like image 195
eugen Avatar answered Oct 22 '22 09:10

eugen