在 JAX-RS 中发出 post 请求时的最佳做法

Best practise when making post request in JAX-RS

在使用 JAX-RS 发出 post 请求时,我看到了一些关于响应状态代码的不同约定。

我看过这个:

  Response.ok(//content or object).build();

我最初的想法是这是错误的,因为状态代码 200 仅表示正常,这是一个宽泛的术语,但由于我们有 'Posted',我认为 201 会更好,因为它还 returns header

里面元素的URI
 Response.created(//content or object).build();

这是我想要实现的目标:

  @POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(String content) throws CityNotFoundException
{
    ReceivedCreateUser receivedUser = gson.fromJson(content, ReceivedCreateUser.class);
    User createdUser = userFacade.createUser(receivedUser.name,
                                             receivedUser.email,
                                             receivedUser.password,
                                             receivedUser.city,
                                             receivedUser.gender,
                                             receivedUser.dateOfBirth);
    if(createdUser == null){
        throw new WebApplicationException(Response.Status.NOT_FOUND);
    }
    return Response.ok(gson.toJson(UserDTO.basic(createdUser))).build();

}

我想将实体添加到响应中,但是 created 只接受 uri 而不是实体。

Response.ok() 并非一直都正常,它可能显示请求已完成但实际上没有创建资源。您可能想要使用 Response.created 或 Response.accepted。如 this link ,你可以看到这完全取决于你后端的业务逻辑。

是否对 POST 请求 return 201 在很大程度上取决于其背后的功能。如果您的端点在系统中创建了一个新实体,那么 201 将是可行的方法,但 POST 也经常用于执行具有大型选项集的搜索请求。在这种情况下,如果有结果或没有结果,则需要 200 或 204。

但是对于 return 具有 POST 和响应 201 的实体,您可以执行类似的操作:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(String content) throws CityNotFoundException
{
    ReceivedCreateUser receivedUser = gson.fromJson(content, ReceivedCreateUser.class);
    User createdUser = userFacade.createUser(receivedUser.name,
                                         receivedUser.email,
                                         receivedUser.password,
                                         receivedUser.city,
                                         receivedUser.gender,
                                         receivedUser.dateOfBirth);
    if(createdUser == null){
       throw new WebApplicationException(Response.Status.NOT_FOUND);
    }
    return Response
       .created(new Uri("http://example.org"))
       .entity(gson.toJson(UserDTO.basic(createdUser)))
       .build();
}

对于客户端和像 Swagger 这样的自动文档,响应类型不是最好的 return,因为它没有太多信息。我特别喜欢return实体直接怎么吼:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public UserDTO createUser(String content) throws CityNotFoundException
{
    ReceivedCreateUser receivedUser = gson.fromJson(content, ReceivedCreateUser.class);
    User createdUser = userFacade.createUser(receivedUser.name,
                                         receivedUser.email,
                                         receivedUser.password,
                                         receivedUser.city,
                                         receivedUser.gender,
                                         receivedUser.dateOfBirth);
    if(createdUser == null){
       throw new WebApplicationException(Response.Status.NOT_FOUND);
    }

    return UserDTO.basic(createdUser);
}

这将 return 变成 Status Code = 200,但有很多方法可以更改为 201。我最喜欢的是覆盖 javax.ws.rs.container.ContainerResponseFilter.filter(...),如下所示:

import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class LocalContainerResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
        throws IOException {
        if (POST.name().equals(requestContext.getMethod()) && OK.value() == responseContext.getStatus()) {
            responseContext.setStatus(CREATED.value());
        }
    }

}

这将改变 JAX-RS 行为 returning 201 所有 POST ok.

更多 2 个提示:

  1. 你可以把一个参数(String内容)改成(ReceivedCreateUser内容);和

  2. 你可以把代码“throw new WebApplicationException”放在userFacade.createUser(...)

  3. 里面