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
,我只是在一行日志语句中被告知忽略了我的所有配置工作。直到(发展较晚。)