我试图以一种特殊的方式处理没有Accept
标题的请求,但不管我做什么,泽西岛似乎一心想要填写一个,所以它总是看起来像请求有一个Accept
标题,即使它没有。
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import static org.junit.Assert.assertEquals;
public class JerseyTestTest extends JerseyTest {
@Path("hello")
public static class HelloResource {
@GET
public String getHello(@Context HttpHeaders httpHeaders) {
String acceptHeader = httpHeaders.getHeaderString(HttpHeaders.ACCEPT);
return acceptHeader != null ? acceptHeader : "No Accept Header";
}
}
@Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
@Test
public void test() {
final String hello = target("hello").request()
.header(HttpHeaders.ACCEPT, null) // null means remove header
.get(String.class);
assertEquals("No Accept Header", hello);
}
}
此测试结果为:
org.junit.ComparisonFailure:
Expected :No Accept Header
Actual :text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
不知何故,Accept
的默认text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
标头会在某处设置。它没有记录,我想知道如何禁用它。我查看了泽西岛的消息来源,但似乎找不到发生这种情况的原因或原因。
更新:当我使用curl命中没有Accept标头的端点时,没有生成的Accept标头,所以问题出现在Jersey Client或Jersey Test环境中。不知何故。
更新2:当使用默认的Grizzly2测试容器或JDK测试容器时,会出现此错误,但不会使用内存测试容器。
答案 0 :(得分:0)
不确定这是否有助于其他人,但我们看到类似的行为,使用我们的客户端代码调用生产中的服务。我们正在使用Jersey 2.21.1。
扩展原帖中的代码,发现以下内容为真:
Accept
标头为空,则Jersey添加默认Accept
标头为空String
,则使用空的Accept
标头Accept
标头有值,则使用我不确定是否有办法告诉Jersey在使用null时不要添加默认值。
public class JerseyAcceptHeaderTest extends JerseyTest {
@Path("hello")
public static class HelloResource {
@GET
public String getHello(@Context HttpHeaders httpHeaders) {
String acceptHeader = httpHeaders.getHeaderString(HttpHeaders.ACCEPT);
System.out.println("SERVER RECEIVED:" + acceptHeader);
if (acceptHeader == null) {
return "Null Accept Header";
} else if (acceptHeader.equals("")) {
return "No Accept Header";
} else {
return acceptHeader;
}
}
}
@Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
/**
* this seems to be a bug in Jersey
* it overrides a null Accept header
*/
@Test
public void test_accept_header_with_null() {
final String acceptHeader = target("hello").request()
.header(HttpHeaders.ACCEPT, null)
.get(String.class);
assertEquals("Null Accept Header", acceptHeader);
}
@Test
public void test_accept_header_with_empty_string() {
final String acceptHeader = target("hello").request()
.header(HttpHeaders.ACCEPT, "")
.get(String.class);
assertEquals("No Accept Header", acceptHeader);
}
@Test
public void test_accept_header_with_spaced_string() {
final String acceptHeader = target("hello").request()
.header(HttpHeaders.ACCEPT, " ")
.get(String.class);
assertEquals("No Accept Header", acceptHeader);
}
@Test
public void test_accept_header_with_value() {
final String acceptHeader = target("hello").request()
.header(HttpHeaders.ACCEPT, "application/json")
.get(String.class);
assertEquals("application/json", acceptHeader);
}
}
答案 1 :(得分:0)
我现在正面临着同样的问题,经过一些研究,最终发现了问题。
WebResourceFactory.invoke(final Object proxy, final Method method, final Object[] {
...
Invocation.Builder builder = newTarget.request()
.headers(headers) // this resets all headers so do this first
.accept(accepts); // if @Produces is defined, propagate values into Accept header; empty array is NO-OP
...
}
请求构建器会自动将API中指定的媒体类型( @Produce )添加到现有的标头中。可悲的是,我没有找到禁用该行为的方法。 因此,我将尝试扩展用于创建客户端的 WebResourceFactory 类(这是最终的),并覆盖该方法调用而不在请求生成器上调用accept 。
请注意,我不认为这是解决方案,而更多地是解决方法。
[编辑] 由于WebResourceFactory是最终版本,因此我复制了它的内容,并删除了请求生成器上的 accept 调用。我有点难看,我知道并希望有人会找到更好的方法。
答案 2 :(得分:0)
我也实现了一种解决方法。如果将用于将Accept标头添加到标头列表的方法的输入:
public void accept(final String... types)
来自ClientRequest
类,为空,我叫WebTarget.request()
而不是WebTarget.request().accept(inputValue)
我认为,如果输入为null或为空字符串,则不应设置Accept标头。因此,我为此主题创建了一个@Jersey问题:https://github.com/eclipse-ee4j/jersey/issues/4407