简体   繁体   English

在 JAX-RS 中为不同的 HTTP 方法返回什么?

[英]What to return for different HTTP methods in JAX-RS?

I am practicing building RESTFUL API's using the RESTEasy implementation.我正在练习使用 RESTEasy 实现构建 RESTFUL API。 But I am still a little bit confused about what should I return according to the HTTP method.但是根据HTTP的方法应该返回什么,我还是有点迷茫。 This is the way that I am doing it for the moment:这是我目前这样做的方式:

  1. @GET returns an Entity @GET返回一个实体
  2. @POST returns an HTTP response with the actual entity created @POST返回一个 HTTP 响应,其中包含创建的实际实体
  3. @PUT returns an HTTP response with the actual entity updated @PUT返回 HTTP 响应,实际实体已更新
  4. @DELETE returns an HTTP response with the actual entity deleted @DELETE返回 HTTP 响应,实际实体已删除

Here is an example of my controller for illustration.这是我的 controller 的示例,用于说明。

@GET
@Path("/{bookId}")
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Book getBookById(@PathParam("bookId") Integer bookId) {
    return bookService.getBookById(bookId);
}

@POST
@Consumes(MediaType.APPLICATION_JSON_VALUE)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Response inertBook(@Valid Book book) {
    return bookService.insertBook(book);
}

@DELETE
@Path("/{bookId}")
public Response deleteBook(@PathParam("bookId") Integer bookId) {
    return bookService.deleteBook(bookId);
}

@PUT
@Path("/{bookId}")
@Consumes(MediaType.APPLICATION_JSON_VALUE)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Response updateBook(@PathParam("bookId") Integer bookId, @Valid Book book) {
    return bookService.updateBook(bookId, book);
}
  1. GET - The client is trying to retrieve a resource or in other words, get a resource. GET - 客户端正在尝试检索资源,或者换句话说,获取资源。 So yes, you should return an entity with a status code of "200 OK" In most cases, it will either be a single resource or a collection resource;所以是的,你应该返回一个状态码为“200 OK”的实体。在大多数情况下,它要么是单个资源,要么是集合资源; in your example, either a single book or all of the books在您的示例中,是一本书或所有书籍

  2. POST - When you create a new resource, generally the client will send the representation of the new book to be created. POST - 当您创建新资源时,通常客户端将发送要创建的新书的表示。 What the client doesn't have is the identifier for the resource or how to access the resource later.客户端没有的是资源的标识符或以后如何访问资源。 What is generally done is a Location header is sent back to the client so the client can later access the resource.通常所做的是将Location header 发送回客户端,以便客户端稍后可以访问资源。 The status of this response should be "201 Created" Optionally, you can send back the same representation the client sent, but including the newly created identifier.此响应的状态应为“201 Created”(可选),您可以发回客户端发送的相同表示,但包括新创建的标识符。 You can see an example in this post .您可以在这篇文章中看到一个示例。

  3. PUT - This is a complete update. PUT - 这是一个完整的更新。 So whatever the client sends completely overwrites the current resource (excluding the identifier).因此,无论客户端发送什么,都会完全覆盖当前资源(不包括标识符)。 So ultimately, the client has all the information already;所以最终,客户已经拥有了所有的信息; no need to send anything back.无需寄回任何东西。 You can just respond back with a "204 No Content" status.您可以回复“204 No Content”状态。 In code terms, you can simply have a void method or return a Response to explicitly set the status.在代码方面,您可以简单地使用 void 方法或返回Response来显式设置状态。

  4. DELETE - If everything goes well with the delete, there is no need to send anything but to let the client know that everything is OK. DELETE - 如果删除一切顺利,则无需发送任何内容,只需让客户端知道一切正常。 So simply sending a "200 OK" response is suitable.所以简单地发送一个“200 OK”响应是合适的。 Optionally, including the deleted representation may be OK.可选地,包括已删除的表示可能是可以的。

These are very general guidelines.这些是非常一般的指导方针。 Everyone has their own style, but most try to follow standards.每个人都有自己的风格,但大多数人都试图遵循标准。 Below are some resources you can dig into to learn more以下是一些您可以深入了解以了解更多信息的资源

Aside在旁边

I was looking at how your service layer implementation (your BookService class) and there are some design flaws.我正在查看您的服务层实现方式(您的 BookService 类),并且存在一些设计缺陷。 Generally, in a tiered application, the lower tiers should not know anything about the tier above it.通常,在分层应用程序中,较低的层不应该知道它上面的层的任何信息。 Here is an example of tiers这是一个层级的例子

  WEB
   ↓
SERVICE
   ↓
  DAO
  • The WEB layer is the REST layer (the JAX-RS code) WEB 层是 REST 层(JAX-RS 代码)
  • The SERVICE layer is the BookService where the business happens SERVICE层是业务发生的BookService
  • The DAO layer is data later where data access happens DAO 层是稍后发生数据访问的数据

In this architecture, the DAO layer should not know about the SERVICE layer and SERVICE layer should not know about the WEB layer.在这个架构中,DAO 层不应该知道 SERVICE 层,SERVICE 层不应该知道 WEB 层。 In your example though, your service knows about Response objects.但是,在您的示例中,您的服务知道Response对象。 The Response should be only used in the WEB layer. Response只能在 WEB 层中使用。 A better implementation might look something like更好的实现可能看起来像

public Response getBook(@PathParam("id") long id) {
    Book book = bookService.findBook(id);
    if (book == null) {
        throw new NotFoundException();
    }
    return book;
}
  

Now the BookService only has the responsibility of finding the book and the resource method handles all of the web logic.现在 BookService 只负责查找书籍,资源方法处理所有 web 逻辑。

Read about Entity Providers , they implement MessageBodyWriter .阅读Entity Providers ,他们实现MessageBodyWriter

RESTEasy is an implementation of JAX-RS (today, a sub-specification of Jakarta EE). RESTEasy 是 JAX-RS(今天,Jakarta EE 的子规范)的一个实现。 In order to understand how the response is generated ( which is what you need to know when thinking about what your resource methods can return ), you should understand how the MessageBodyWriter works.为了了解响应是如何生成的(这是您在考虑资源方法可以返回什么时需要了解的内容),您应该了解MessageBodyWriter的工作原理。

Resource Method can return almost anything, including String , Response , some custom bean, etc., but it's not that much about what your method returns, it's rather how (as which MediaType) your MessageBodyWriter implementation converts output stream into HTTP response body. Resource Method can return almost anything, including String , Response , some custom bean, etc., but it's not that much about what your method returns, it's rather how (as which MediaType) your MessageBodyWriter implementation converts output stream into HTTP response body.

Value returned from the JAX-RS resource method is converted into an HTTP response body by an Entity Provider (that is a MessageBodyWriter implementation), and depending on what you instruct your method to set as a MIME type (with @Produces , on top of method) of the response and whether or not you have a corresponding converter (Entity Provider, ie MessageBodyWriter) on your classpath, JAX-RS will:从 JAX-RS 资源方法返回的值由实体提供程序(即MessageBodyWriter实现)转换为 HTTP 响应正文,具体取决于您指示方法设置为 MIME 类型的内容(使用@Produces ,在方法)以及您的类路径上是否有相应的转换器(实体提供程序,即 MessageBodyWriter),JAX-RS 将:

  1. look for the @Produces value;寻找@Produces值;
  2. then look for the corresponding converter / MessageBodyWriter (will throw a conversion exception if no required implementation found on classpath);然后查找对应的转换器/ MessageBodyWriter (如果在类路径上找不到所需的实现,将抛出转换异常);
  3. serialize your output stream into whatever you instruct it to return with @Produces(MediaType.TypeHere) , and will return it.将您的 output stream 序列化为您指示它返回的任何内容@Produces(MediaType.TypeHere) ,并将返回它。

Remember, that returning a non-void Java type results in a 200 OK response, while a void method results in a 204 No Content response.请记住,返回非 void Java 类型会导致 200 OK 响应,而 void 方法会导致 204 No Content 响应。

@Produces specifies MIME type of response body, that your resource method should produce, by adding a Content-type header to the response. @Produces通过向响应添加Content-type header 来指定您的资源方法应生成的响应正文的 MIME 类型。 For different MIME types, you will need a corresponding converter library (implementation of MessageBodyWriter ) to return whatever you're indicating as your Media/MIME type.对于不同的 MIME 类型,您将需要一个相应的转换器库( MessageBodyWriter的实现)来返回您指示为 Media/MIME 类型的任何内容。

A side-note: JAX-RS is a specification for RESTful web services, which implies, that in most of the cases, you better work with JSON.附注:JAX-RS 是 RESTful web 服务的规范,这意味着在大多数情况下,您最好使用 JSON。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM