java Web服务响应对象vs生成

java Web服务响应对象vs生成,java,jax-rs,Java,Jax Rs,我尝试使用java Web服务,并尝试遵循几个教程示例 在其中一个示例中,我看到@products注释用于指定返回的响应类型 例如: @GET @Produces(MediaType.TEXT_PLAIN) public String sayPlainTextHello() { return "Hello Jersey"; } @GET @Path("/{param}") public Response getMsg(@PathParam("param") String msg) {

我尝试使用java Web服务,并尝试遵循几个教程示例

在其中一个示例中,我看到@products注释用于指定返回的响应类型

例如:

@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
    return "Hello Jersey";
}
@GET
@Path("/{param}")
public Response getMsg(@PathParam("param") String msg) {

    String output = "Jersey say : " + msg;

    return Response.status(200).entity(output).build();

}
但在另一个例子中,我看到响应对象被用作响应

例如:

@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
    return "Hello Jersey";
}
@GET
@Path("/{param}")
public Response getMsg(@PathParam("param") String msg) {

    String output = "Jersey say : " + msg;

    return Response.status(200).entity(output).build();

}
问题:

  • 哪一种是发送响应的正确方法-响应对象或@products注释
  • 当两种情况都可以使用时

  • 最好的方法是始终将两者结合使用。原因如下

    @products基本上定义了响应的内容类型(MIME-TYPE)。但差不多就这些了。它没有定义HTTP状态代码(错误/成功/服务器错误等)@生成注释只是通过不显式指定响应中的内容类型来简化您的工作

    现在为什么要使用Response而不是String作为返回类型?这里有一个例子

    让我们考虑以下代码:

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String sayPlainTextHello() {
        try
        {
             return someRemoteServerApi.getHelloString();
        }
        catch(exception ex)
        {
             return getErrorMessageString();
        }
    }
    
    现在让我们假设远程服务器api无法返回,这导致了某种错误。现在,您希望将错误与错误代码一起返回给客户机(因为坦率地说,客户机在开发时只关心错误消息字符串。一旦开发了客户机,他们的API将完全基于HTTP返回状态代码)

    因此,在上面的示例中,假设您返回一个错误json字符串,如(getErrorMessageString()):

    但是,您的实际HTTP状态代码仍然是“200OK”,因为响应仍然是一个字符串,并且响应顺利通过。客户如何知道API中是否出现了问题?他将不得不解析json字符串(出错时),并确定出错的地方

    基本上,在上述情况下,您的成功和失败都将具有相同的HTTP状态返回代码,这对客户端没有多大帮助。相反,上述代码应该更改如下内容:

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response sayPlainTextHello() {
        try
        {
             return Response.status(200).entity(someRemoteServerApi.getHelloString()).build();
        }
        catch(exception ex)
        {
             return Response.status(500).entity(getErrorMessageString()).build();
        }
    }
    
    最后,

    关于回答您的两个问题:

    1) @products与将发送何种响应无关。它只设置要发送的响应对象的内容类型。默认情况下,JAX-RS将放置200个OK响应,当然,除非发生未捕获的异常。那么它可能会返回500。基本上,您将依赖JAX-RS为您返回错误代码,这不是很好。作为实现者,您应该确定应该向客户机发送哪种类型的最有意义的错误代码和错误消息

    2) 我将始终使用Response作为方法的返回类型,以及每个方法的@products和@Consumes注释。如果您认为您的全部资源(java资源类中的所有方法)使用相同的@products和@Consumes mime类型(在大多数情况下是application/json),那么您可以在类级别本身定义它,大致如下:

    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/rest/someResource")
    public class MyResource()
    {
         @Path("/{resourceId")
         @GET
         public Response getResource(@PathParam("resourceId") String id)
         {
              doStuffAndReturnResponse();
         }
    }
    
    默认情况下,这会将@products和@consumes注释应用于所有资源方法,如果您希望在某个特定的资源方法上有特定的内容,您可以通过仅为该特定方法提供注释来覆盖它


    我希望我已经解释得足够好了!快乐编码

    如果你觉得有帮助,请把答案填上!干杯