How do I get a test / client jersey to not fill in the default Accept header?

I am trying to process a request without an Accept header in a specific way, but Jersey seems to struggle to fill it, no matter what I do, so it always looks like the request has Accept , even if it is not.

 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); } } 

This test result:

 org.junit.ComparisonFailure: Expected :No Accept Header Actual :text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 

Somehow there is a default Accept header text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 , which is set somewhere. This is not documented, and I would like to figure out how to disable it. I looked at a source in Jersey but cannot find where this is happening or why.

Update: when I use curl to get to the endpoint without an Accept header, there is no Accept header generated, so the problem is that the problem is in the Jersey client or in the Jersey test environment.

Update 2: This error occurs when using the default Grizzly2 test container or the JDK test container, but NOT with the In Memory test container.

+7
source share
2 answers

Not sure if this helps anyone else, but we are seeing similar behavior causing a service in production with our client code. We use Jersey 2.21.1.

I deployed the code from the original message and found the following:

  • If the Accept header is null, then Jersey adds a default value.
  • If the Accept header is an empty String , then an empty Accept header is used.
  • if the header Accept value that it is used

I'm not sure if there is a way to tell jersey not to add a default when null is used.

 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); } } 
0
source

I am facing the same problem right now, and after some research, I ended up finding the problem.

 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 ... } 

The query designer automatically adds media types specified in the API ( @Produce ) to existing headers. Unfortunately, I did not find a way to disable this behavior. Therefore, I will try to extend the WebResourceFactory class (which is final) used to create my client and override this method, invoking so as not to call accept on the request collector .

Remember that I do not see this as a solution, but rather as a workaround .

[EDIT] Since WebResourceFactory is final, I duplicated its contents and removed the accept call in the query builder. A little ugly, I know and hope that someone will find a better way.

0
source

Source: https://habr.com/ru/post/1012777/


All Articles