2013-04-30 120 views
33

我正在構建REST API。我的問題是,在使用Jersey時,我的服務構建和返回Response對象或返回bean或集合之間有什麼區別。我只關心成功的電話,我正在拋出錯誤和特殊情況的適當例外。在JAX RS中,返回Response和Bean或Bean的集合(DTO)之間的區別

這裏有一個例子:

@Produces(MediaType.APPLICATION_JSON) 
public Response search(FooBean foo){ 
    List<FooBean> results = bar.search(foo); 
    return Response.ok(results).build(); 
} 

@Produces(MediaType.APPLICATION_JSON) 
public List<FooBean> search(FooBean foo){ 
    List<FooBean> results = bar.search(foo); 
    return results; 
} 

我見過用這兩個例子中,我更喜歡第二種方案中,只是爲了更容易地識別服務方法。我已經檢查了對這兩種方法的反應,它們似乎是相同的。

想法?

+1

他們是相同的,考慮到你無法返回一些'Exception'類像你說的。 'Response'提供返回任何類型的對象的選項,並設置一個'HttpStatus'。在這種情況下,它會產生'200 OK'。但是你不能像使用Response一樣切換到另一個狀態。當然,這是我的看法,但我喜歡'Response'方式。 – 2013-04-30 17:03:17

+0

您的意思是您可以使用Response對象切換到不同的響應狀態? 如果我返回列表,響應狀態也是200 OK。 – 2013-04-30 17:44:12

+2

是的,你可以切換,如果你想。默認情況下'Response.ok()。entity(entity).build();'如果實體不爲空則返回'200 OK',否則返回'204 NO CONTENT'。你可以用'Response.ok()。entity(entity).status(Status.OK).build();'強制返回'200 OK'狀態,即使實體爲空; – 2013-04-30 19:45:46

回答

31

的差異在JAX-RS規範解釋:

3.3.3返回類型

資源的方法可以返回void,響應,GenericEntity,或其他Java類型,這些返回類型被映射到一個響應實體體如下:在一個空的實體主體

空隙
結果與一個204狀態碼。

響應
從響應的實體屬性映射的實體主體的結果與由狀態屬性指定的狀態代碼的結果。空返回值會導致204狀態碼。如果未設置響應的狀態屬性:對於非空實體屬性使用200狀態碼,如果實體屬性爲空,則使用204狀態碼。

GenericEntity
從GenericEntity的Entity屬性映射的實體主體中的結果。如果返回值不爲空,則使用200狀態碼,空返回值將生成204狀態碼。

其他
結果在一個實體主體從返回的實例的類映射。如果返回值不爲空,則使用200狀態碼,空返回值將生成204狀態碼。

方法需要提供一個響應額外的元數據應該返回響應的情況下,ResponseBuilder類提供了一個方便的方式來創建使用生成器模式的響應實例。

「常規」豆中幾乎爲Response相同的方式映射過來,不同之處在於一個Response允許您設置額外的元數據(響應報頭,專業地位,專業的內容類型,等等)。至於哪一個使用,這完全取決於你自己決定 - Response給你更多的靈活性,但常規豆更多'自我記錄'。

+1

以下是該規範的鏈接:http://download.oracle.com/otndocs/jcp/jaxrs-2_0-fr-spec/index.html – 2016-11-14 18:18:39

8

如果您希望始終返回響應200 - OK,則可以捕獲並處理在您的方法返回結果之前可能發生的所有異常,包括攔截或WebApplicationException。所以,這兩種方法都會產生相同的響應。

唯一性差異是在特定的場景中,像返回null對象或創建對象,如下例所示:

@POST 
@Consumes("application/json") 
public Response post(String content) { 
    URI createdUri = ... 
    Object createdContent = create(content); 
    return Response.created(createdUri).entity(createdContent).build(); 
} 

在這種情況下,返回將是201 - CREATED(隨着URI來訪問所創建的對象)

所以,下面的方法:

@POST 
@Consumes("application/json") 
public Object post(String content) { 
    URI createdUri = ... 
    Object createdContent = create(content); 
    return createdContent; 
} 

...將返回響應200 - OK

如果您不關心客戶端將收到哪種響應狀態,則可以毫無問題地使用任何聲明。

來源:Jersey

+0

好的解決方案,因爲大多數情況下我們使用對象來操作,而不僅僅是使用字符串。所以,我有一個問題 - 如何從Response中檢索對象並獲取它的xml或json表示形式? – Nikolas 2015-01-27 15:45:53

0

我個人認爲,如果響應包含DTO(Bean/Bean的集合),那麼休息服務總是必須返回DTO,但不是Response對象。

的動機:早或晚,你會被要求做休息服務客戶端更容易的使用,通過提供其餘客戶端API。通常,您必須爲其提取其餘接口,並將其與您的其餘服務一起實施。這些休息接口由您的其他客戶端的客戶端使用。

從客戶的角度來看,處理DTO和普通響應之間存在巨大差異。在迴應的情況下使用,您的客戶端被強制:

  1. 檢查明確地迴應代碼來處理全成響應
  2. 處理錯誤,通過檢查你的代碼的迴應明確
  3. 轉換身體成DTO由他本人。

這意味着處理Response與在方法中返回錯誤代碼非常相似,這被認爲是非常糟糕的做法。爲了在一個地方處理錯誤,使用了異常(我沒有談論FP處理錯誤的方式,這是最好的)。

那麼可以這樣做:

  1. 如果請求被成功處理,轉換成你的休息業務數據到DTO /豆和返回。
  2. 如果驗證失敗或出現問題,請在您的休息服務中引發異常。也許一個默認的異常映射器不適合你,所以你必須實現你自己的異常映射器。

所以如果事先想想,你應該返回DTO。

一個用例,當應該返回普通的Response時 - 例如當您導出文件時。看來JAX RS不允許返回InputStream對象。不確定,必須檢查。

的其他用途的情況下,被@Perception指出,但它更多的是一個例外,不是規則:

中的方法需要提供額外的元數據與響應 應該返回響應的情況下, ResponseBuilder類 提供了一種使用 構建器模式創建Response實例的便捷方法。

注:這是JAX RS一個一般性的問題,不依賴於具體實現,像RestEasy的或澤西

相關問題