2012-06-21 109 views
1

我使用jersey-client來使用REST服務。 我需要請求的實體和Last-Modified標頭。jersey-client在NPE中拋出NPE ClientResponse.getLastModified()

所以我做到以下幾點:

ClientResponse response = webResource.get(ClientResponse.class); 
Person person = response.getEntity(Person.class); 

工程。我得到一個響應,我可以將實體(這是XML)編組到我的POJO中。 當我調試並查看響應的標題時,我發現有一個Last-Modified標題集。

但是,當我嘗試通過

response.getLastModified(); 

提取日期我在URLConnectionClientHandler得到了NPE的地方。

有沒有人有線索我做錯了什麼?

編輯:的要求跟蹤

java.lang.NullPointerException: null 
at com.sun.jersey.api.client.ClientResponse.getLastModified(ClientResponse.java:647) ~[jersey-client-1.12.jar:1.12] 
at a.o.u.user.dao.impl.uds.PersonenUdsClient.getPerson(PersonenUdsClient.java:103) ~[um-user-2.5.0-Beta1-SNAPSHOT.jar:na] 
at a.o.u.user.dao.impl.UserDaoUdsImpl.mergeWithUdsUser(UserDaoUdsImpl.java:282) ~[um-user-2.5.0-Beta1-SNAPSHOT.jar:na] 
at a.o.u.user.dao.impl.UserDaoUdsImpl.getUserWithEmail(UserDaoUdsImpl.java:124) ~[um-user-2.5.0-Beta1-SNAPSHOT.jar:na] 
at ... 

編輯:爲NPE建議我挖成的代碼。我想我找到了問題。除了球衣客戶端之外,我還有類路徑中的cxf。球衣和cxf均提供了一個名爲RuntimeDelegateImpl的課程。但CXFs版本不包含DateHeaderDelegate。我認爲RuntimeDelegateImpl的錯誤版本(CXFs)被拍攝。

現在我還沒有找到我可以如何明確設置RuntimeDelegateImpl使用。

+0

給我們一個堆棧跟蹤。 – npe

回答

1

要使它成爲一個包裹。

問題是我在類路徑中都有jersey-client和cxf。這兩個RuntimeDelegateImpl。但CXFs版本不包含DateHeaderDelegate。採用RuntimeDelegateImpl的錯誤版本(CXF)。

我通過檢索Last-Modified頭 '手動' 來解決這個問題:

private Date getLastModified(ClientResponse response){ 
    String lastModifiedString = response.getHeaders().getFirst(
      "Last-Modified"); 
    if (StringUtils.isEmpty(lastModifiedString)) { 
     LOG.warn("Expect to get Last-Modified header when retrieving a Person by pnr " 
       + "but there is none."); 
     return null; 
    } else { 
     try { 
      // format is Thu, 21 Jun 2012 08:00:42 GMT 
      return new SimpleDateFormat(
        "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US) 
        .parse(lastModifiedString); 
     } catch (ParseException e) { 
      LOG.error("Could not parse Last-Modified date " 
        + e.getMessage()); 
      return null; 
     } 
    } 
} 

感謝名單向NPE的提示。

2

Use the source, Luke

ClientResponse#getLastModified()的版本實現1.12如下所示:

/*639*/ /** 
/*640*/ * Get the last modified date. 
/*641*/ * 
/*642*/ * @return the last modified date, otherwise <code>null</code> if not present. 
/*643*/ */ 
/*644*/ public Date getLastModified() { 
/*645*/  String d = getHeaders().getFirst("Last-Modified"); 
/*646*/ 
/*647*/  return (d != null) ? dateDelegate.fromString(d) : null; 
/*648*/ } 

你在排隊647獲得NullPointerException,所以它的出現,是dateDelegatenull。現在,dateDelegate對象在管線321初始化,像這樣:現在

/*321*/ protected static final HeaderDelegate<Date> dateDelegate = 
/*322*/   RuntimeDelegate.getInstance().createHeaderDelegate(Date.class); 

,外地final,所以它不能在此初始化之後改變 - 這意味着dateDelegate是從一開始就null - 這意味着, 您有某種配置問題,並且未創建委託。

此外,在AbstractRuntimeDelegate類(source for 1.12 here)創建的代表,就像這樣:

/* 88*/ map.put(Date.class, _createHeaderDelegate(Date.class)); 

這兔子洞進入越來越深,所以我要停在這裏,但你知道的方式。

而最後,但並非最不重要 - 調試器是你的朋友,我的朋友;-)

+0

是真的,來源總是有用的。但我認爲像dateDelate這樣的東西應該在那裏,沒有我做一些特別的事情。我看起來對我很重要。我的init代碼不正確? 我用Client.create()初始化我的客戶端;然後我得到我的WebResource,像這樣getClient()。resource(baseUrl); 我也可以使用ClientConfig來創建客戶端,但是那裏沒有什麼與seeDelegate相關的。 – nebenmir

+0

好吧,如果你深入挖掘,你會發現在'jersey-core.jar'META-INF/services'文件夾中有一個'com.sun.jersey.spi.HeaderDelegateProvider'文件,用於定義代表們。除非你正在使用這些JAR(如刪除'META-INF'),我真的不知道它爲什麼沒有加載。我想你需要調試我指出的Jersey的初始化代碼,以便找出答案。 – npe