2016-12-01 46 views
6

我試圖以一種特殊的方式處理沒有Accept頭的請求,但澤西似乎很想填寫一個,不管我做什麼,所以它總是看起來像請求有一個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 

不知怎的,有一種text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2默認Accept頭時設置的地方。它沒有記錄,我很想弄清楚如何禁用它。我瀏覽了澤西島的資源,但似乎無法找到發生這種情況的原因或原因。

更新:當我使用curl命中沒有Accept頭的端點時,沒有生成Accept頭,所以問題出在Jersey Client或Jersey Test環境。

更新2:使用默認的Grizzly2測試容器或JDK測試容器時出現此錯誤,但不包含In Memory測試容器。

+0

它可能在爲請求創建UserAgent時設置。有一個很好的洞察https://tools.ietf.org/html/rfc7231#section-5.3.2。 同樣爲了解決上述問題,你可以嘗試在你的Resource類中重寫帶有null/empty值的Accept頭? – nullpointer

+0

@nullpointer我在澤西島發現了添加用戶代理請求的代碼,並且我沒有看到附近添加了Accept頭的任何代碼,所以不,當它被添加時不是。我確切知道接受頭文件的用途,並且我已經閱讀了RFC並將其引用了很多。我不知道你的意思是重寫Resource類中的Accept頭。 Resource類是服務器上的內容,Jersey文檔中沒有關於重寫頭文件的任何內容,而且我也沒有試圖替換接收到的Accept頭文件。我想看看Accept頭是什麼,或者沒有。 – postfuturist

+0

你用wget或curl作爲客戶端嘗試過嗎? @Test方法的確切作用是什麼? – gsl

回答

0

不知道這是否有助於其他人,但我們看到類似的行爲,用我們的客戶代碼調用生產中的服務。我們正在使用Jersey 2.21.1。

擴大從原來的職位代碼並發現以下是真實的:

  • 如果Accept頭爲null,則澤西添加默認
  • 如果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); 
    } 

}