Reputation: 85
Hi I've got a scenario where I would like to control the content type return by a jersey web-service dynamically without using request header content-type.
Currently I do the standard thing:
@Produces( {"application/xml", "application/json"})
public ContactsConverter getSearchContacts()
So by default I'll get xml back. However, if I want to get a json object back, i'll have to set "Content-Type: application/json" in my request header. This is currently not an option for me because the request is coming from an cross domain ajax call, where the content-type will always be /. So therefore, I'd like to use a flag in my request or something clever to specify the content-type returned. I've looked around but haven't seen anything helpful, one suggestion is to sent json as the default, but this is something I'd want to avoid doing.
Upvotes: 1
Views: 4158
Reputation: 8699
Well first of all, I think that Jersey is doing the wrong thing here, since Content-Type is a header that describes the content of the request/response and you aren't including any content with the request, it should actually be basing its behaviour on the Accepts header instead, but leaving that aside....
Just because it's an ajax call, it doesn't mean that the content-type will always be /, on the client you can call setRequestHeader like so:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://myjaxrs-server/getSearchContacts");
xhr.onreadystatechange = function() {
/* normal javascript to deal with the response goes here */
};
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send("data i'm posting");
Setting the Content-Type header on a CORS request will cause a pre-flight to occur. You have to support the preflight in the server code or the CORS request will be rejected. Provide your normal code for getSearchContacts, but the preflight will come in on with an OPTIONS method:
@OPTIONS
public Response preflight(
@HeaderParam("Access-Control-Request-Method") String requestMethod,
@HeaderParam("Origin") String origin,
@HeaderParam("Access-Control-Request-Headers") String requestHeaders) {
return Response
.ok()
.header("Access-Control-Allow-Origin", "*") // TODO replace with specific origin
.header("Access-Control-Allow-Headers", "Content-Type")
.build();
}
Now the CORS request with the custom headers will be allowed.
It's easy to get this wrong : as far as I can tell, even the google spreadsheet api doesn't respond correctly to preflights, meaning that you can't actually change any data from javascript.
Upvotes: 2