2013-04-30 116 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的或泽西

相关问题