gpt4 book ai didi

java - 无法使用 Jersey 客户端过滤器覆盖响应 header

转载 作者:搜寻专家 更新时间:2023-11-01 01:10:49 28 4
gpt4 key购买 nike

我正在尝试使用 Jersey 客户端 API 来使用第三方 REST 服务。我计划使用自动 POJO 反序列化从 JSON 响应到 Java 对象。

不幸的是,第三方服务使用内容类型“text/javascript” 返回响应。我的 Jersey 客户端无法理解应将其视为 JSON 对象,因此无法反序列化该对象。

我编写了一个简单的 Jersey 服务器应用程序,通过将内容类型从 "text/javascript" 更改为 "application/json" 来验证反序列化是否有效。

有了这些信息,我开始使用 Jersey 客户端过滤器来修改响应 header 。代码来自this question作者的评论.事实上,问题似乎与我的问题完全相同 - 但是回答者错误回答了问题并展示了如何修改请求 header (而不是响应 header ).原作者能够使用答案来创建他的解决方案,但是,他提出的解决方案似乎不起作用。

过滤代码为:

client.addFilter(new ClientFilter() {
@Override public ClientResponse handle(ClientRequest cr)
throws ClientHandlerException {
ClientResponse response = getNext().handle(cr);
response.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
return response;
}
});

但是,当执行时,会引发 UnsupportedOperationException:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.clear(Collections.java:1035)
at com.sun.jersey.core.util.StringKeyIgnoreCaseMultivaluedMap.putSingle(StringKeyIgnoreCaseMultivaluedMap.java:78)
at com.sun.jersey.core.util.StringKeyIgnoreCaseMultivaluedMap.putSingle(StringKeyIgnoreCaseMultivaluedMap.java:56)
at App$1.handle(App.java:49)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:507)
at App.main(App.java:63)

返回的 header 似乎包装在一个不可修改的集合中。

然后我尝试将所有 header 复制到一个新集合,但是我无法看到将 header 映射设置返回到响应中。

最后,我想也许我可以创建一个新的 ClientResponse 来包含我修改过的 header 。但是,ClientResponse 的构造函数具有以下签名:

public ClientResponse(int status, 
InBoundHeaders headers,
InputStream entity,
MessageBodyWorkers workers)

从原始文件中复制statusheadersentity 变量是微不足道的。但是,我看不到获取对 workers 字段的引用的方法。

如何使用 Jersey 客户端过滤器将响应 header 从 "text/javascript" 修改为 "application/json" 以便我的 POJO 反序列化工作?

最佳答案

在 Jersey 2 中,注册一个 ClientResponseFilter 的实现使用 ClientConfig 来操作传入响应的 HTTP header 。

例如,这似乎可以很好地与 Jersey 2.3.1 一起用于操作 HTTP header :

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.ClientRequestContext;

import org.glassfish.jersey.client.ClientConfig;

/* Ensure that there is an "application/xml" Content-Type header on
* successful responses without a content type header. */
@Provider
public static class EnsureXmlContentTypeFilter implements ClientResponseFilter {
@Override
public void filter(ClientRequestContext requestContext,
ClientResponseContext responseContext) {
if (200 == responseContext.getStatus() &&
null == responseContext.getHeaderString(HttpHeaders.CONTENT_TYPE)) {

responseContext.getHeaders().add(
HttpHeaders.CONTENT_TYPE, "application/xml"
);

}
}
}

private final ClientConfig config = new ClientConfig()
// Registering this filter adds a "Content-Type: application/xml"
// header to each response that lacks Content-Type headers.
.register(EnsureXmlContentTypeFilter.class)
;
private final Client client = ClientBuilder.newClient(config);

关于过滤器和拦截器的 Jersey 文档并不完美,但它确实有一些指向相关类的 javadoc 的链接:https://jersey.java.net/documentation/latest/filters-and-interceptors.html

我正在从一个以 XML 内容响应但缺少“Content-Type:application/xml” header 的服务中获取 XML 响应。注册 MessageBodyReader 可能是更好的方法,但上述方法在我使用该服务的 API 时有效。

关于java - 无法使用 Jersey 客户端过滤器覆盖响应 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12737795/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com