问题描述
我有一个场景,我想不使用请求标头content-type来动态控制jersey Web服务返回的内容类型.
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()
因此,默认情况下,我会返回xml.但是,如果我想找回json对象,则必须在我的请求标头中设置"Content-Type:application/json".对于我来说,这目前不是一个选择,因为请求来自跨域ajax调用,其中内容类型始终为/.因此,我想在请求中使用标记或巧妙的方法来指定返回的内容类型.我环顾四周,但没有发现任何帮助,一个建议是将json作为默认值发送,但这是我想避免的事情.
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.
推荐答案
首先,我认为Jersey在这里做错了事情,因为Content-Type是描述请求/响应内容的标头,并且您并未在请求中包含任何内容,实际上它应该将其行为基于Accepts标头,但应将其放在一边…….
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....
仅仅因为它是ajax调用,并不意味着内容类型将始终为/,在客户端上,您可以像下面这样调用setRequestHeader:
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");
在CORS请求上设置Content-Type标头将导致预检.您必须在服务器代码中支持印前检查,否则CORS请求将被拒绝.提供用于getSearchContacts的常规代码,但预检将通过OPTIONS方法进行:
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();
}
现在将允许带有自定义标头的CORS请求.
Now the CORS request with the custom headers will be allowed.
容易出错:据我所知,即使Google电子表格api也无法正确响应预检,这意味着您实际上无法从javascript更改任何数据.
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.
这篇关于球衣内容类型定制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!