Jersey ApacheConnector不处理在WriterInterceptor中设置的请求头
使用Jersey ApacheConnector不处理在WriterInterceptor中设置的请求头,jersey,jersey-client,Jersey,Jersey Client,使用ApacheConnector配置我的Jersey客户端时遇到问题。它似乎忽略了我在WriterInterceptor中定义的所有请求头。当我在WriteTo(WriteInterceptorContext)周围的WriteInterceptor中设置断点时,我可以看出调用了WriteInterceptor。与此相反,我可以观察到,InputStream的修改被保留 下面是一个可运行的示例,演示了我的问题: 公共类ApacheConnector问题演示扩展了Jersey测试{ 私有静态最终记
ApacheConnector
配置我的Jersey客户端时遇到问题。它似乎忽略了我在WriterInterceptor
中定义的所有请求头。当我在WriteTo(WriteInterceptorContext)
周围的WriteInterceptor中设置断点时,我可以看出调用了WriteInterceptor
。与此相反,我可以观察到,InputStream
的修改被保留
下面是一个可运行的示例,演示了我的问题:
公共类ApacheConnector问题演示扩展了Jersey测试{
私有静态最终记录器Logger=Logger.getLogger(JerseyTest.class.getName());
私有静态最终字符串QUESTION=“baz”,ANSWER=“qux”;
私有静态最终字符串REQUEST\u HEADER\u NAME\u CLIENT=“foo cl”,REQUEST\u HEADER\u VALUE\u CLIENT=“bar cl”;
私有静态最终字符串请求\头\名\拦截器=“foo ic”,请求\头\值\拦截器=“bar ic”;
专用静态最终int MAX_连接=100;
私有静态最终字符串路径=“/”;
@路径(路径)
公共静态类TestResource{
@职位
公共字符串句柄(InputStream questionStream,
@HeaderParam(请求\标题\名称\客户端)字符串客户端,
@HeaderParam(请求\标题\名称\拦截器)字符串拦截器)
抛出IOException{
assertEquals(请求\u头\u值\u客户端,客户端);
//在这里,在客户端的writer拦截器中设置的头丢失。
assertEquals(请求\头\值\拦截器,拦截器);
//但是,输入流被gzip压缩,因此部分应用了WriterInterceptor。
assertEquals(问题,新扫描器(新的gzip输入流(问题流)).nextLine();
返回答案;
}
}
@提供者
@优先级(优先级。实体\编码器)
公共静态类ClientInterceptor实现WriterInterceptor{
@凌驾
WriteTo周围的公共无效(WriterInterceptorContext上下文)
抛出IOException、WebApplicationException{
context.getHeaders().add(请求\u头\u名称\u拦截器、请求\u头\u值\u拦截器);
setOutputStream(新的gzip输出流(context.getOutputStream());
context.procedure();
}
}
@凌驾
受保护的应用程序配置(){
启用(TestProperties.LOG\u流量);
启用(TestProperties.DUMP_实体);
返回新的ResourceConfig(TestResource.class);
}
@凌驾
受保护的客户端getClient(TestContainer tc、ApplicationHandler ApplicationHandler){
ClientConfig ClientConfig=tc.getClientConfig()==null?新建ClientConfig():tc.getClientConfig();
属性(ApacheClientProperties.CONNECTION_MANAGER、makeConnectionManager(MAX_CONNECTIONS));
register(ClientInterceptor.class);
//如果我不使用Apache连接器,我可以避免这个问题。
connector(新的ApacheConnector(clientConfig));
if(isEnabled(TestProperties.LOG_流量)){
register(新的LoggingFilter(LOGGER,isEnabled(TestProperties.DUMP_实体));
}
配置客户端(clientConfig);
返回ClientBuilder.newClient(clientConfig);
}
专用静态客户端连接管理器makeConnectionManager(int-maxConnections){
PoolgClientConnectionManager connectionManager=新的PoolgClientConnectionManager();
connectionManager.setMaxTotal(maxConnections);
connectionManager.setDefaultMaxPerRoute(maxConnections);
返回连接管理器;
}
@试验
public void testInterceptors()引发异常{
响应=目标(路径)
.request()
.header(请求\头\名称\客户端、请求\头\值\客户端)
.post(实体文本(问题));
assertEquals(200,response.getStatus());
assertEquals(ANSWER,response.readEntity(String.class));
}
}
我想使用ApacheConnector
,以便通过poolgclientconnectionmanager
优化并发请求。我把配置搞砸了吗
PS:使用GrizzlyConnector
时会出现完全相同的问题经过进一步研究,我认为这是使用HttpURLConnection
的默认连接器中的一个错误行为。正如我在这篇文章中解释的那样:
而过滤器主要用于处理请求和
HTTP头、URI和/或HTTP方法等响应参数,
拦截器旨在通过操纵实体来操纵实体
实体输入/输出流
WriterInterceptor
不应操作头值,而{Client,Server}RequestFilter
不应操作实体流。如果需要同时使用这两个组件,那么这两个组件都应该捆绑在一个javax.ws.rs.core.Feature
中,或者捆绑在实现两个接口的同一个类中。(如果需要设置两个不同的优先级,这可能会有问题。)
但这一切都非常不幸,因为JerseyTest
使用了连接器
,该连接器使用了HttpURLConnection
,因此我的所有单元测试都成功了,而实际应用程序由于配置了ApacheConnector
而行为不当。此外,我希望泽西不会压制变革,而是给我一些例外。(这是我对Jersey的一个普遍问题。例如,当我使用了太新版本的ClientConnectionManager
时,接口被重命名为HttpClientConnectionManager
,我只是在一行日志语句中被告知忽略了我的所有配置工作。直到(发展较晚。)