我正在尝试java webservices并试图遵循几个教程示例。
在其中一个示例中,我看到@Produces注释用于指定要返回的响应类型。
示例:
@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello Jersey";
}
但在另一种情况下,我看到Response对象被用作响应...
示例:
@GET
@Path("/{param}")
public Response getMsg(@PathParam("param") String msg) {
String output = "Jersey say : " + msg;
return Response.status(200).entity(output).build();
}
问题:
答案 0 :(得分:14)
最好的方法是始终使用两者的组合。这就是为什么
@Produces基本上定义了Response的CONTENT-TYPE(MIME-TYPE)。但这几乎就是全部。它没有定义HTTP状态代码(出错/成功/服务器错误等)。 @Produces注释只是通过不明确指定内容类型在响应中的内容,使您的生活更轻松。
现在为什么要使用Response而不是“String”作为返回类型?这是一个例子
让我们考虑以下代码:
@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
try
{
return someRemoteServerApi.getHelloString();
}
catch(exception ex)
{
return getErrorMessageString();
}
}
现在假设远程服务器api无法返回,这导致某种错误。现在,您希望使用错误代码将错误返回给客户端ALONG(因为坦率地说,客户端只会在开发时关注错误消息字符串。一旦客户端开发完成,他们将仅将其apu基于HTTP返回状态代码)。
因此,在上面的例子中,假设您返回一个错误json String,例如(getErrorMessageString()):
{
"error":500
"message": "something went wrong"
}
但是,你的实际HTTP状态代码仍然是“200 OK”,因为Response仍然是一个字符串,响应也很好。客户如何知道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)@Produces与将发送什么类型的响应无关。它只是在您要发送的任何Response对象上设置内容类型。默认情况下,JAX-RS将放置200 OK响应,除非当然发生未被捕获的异常。然后它可能会返回500.基本上,你将依靠JAX-RS为你返回错误代码,这不是很好。作为实施者,您应确定应将哪种错误代码和错误消息发送给最有意义的客户端
2)我将始终使用Response作为方法的返回类型,以及每种方法的@Produces和@Consumes注释。如果您认为您的完整资源(java资源类中的所有方法)使用相同的@Produces和@Consumes mime-type(在大多数情况下是它的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();
}
}
默认情况下,这会将@produces和@consumes注释应用于所有资源方法,如果您想要某些特定资源方法的特定内容,则可以通过仅为该特定方法提供注释来覆盖它。
我希望我已经解释得足够好了!快乐的编码!