使用JAX-RS(Jersey)和@RolesAllowed自定义HTTP状态响应

使用我非常简单的JAX-RS服务,我使用Tomcat和JDBC领域进行身份validation,因此我正在使用JSR 250注释。

问题是我想在HTTP状态响应中返回自定义消息体。 状态代码(403)应保持不变。 例如,我的服务如下所示:

@RolesAllowed({ "ADMIN" }) @Path("/users") public class UsersService { @GET @Produces(MediaType.TEXT_PLAIN) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public String getUsers() { // get users ... return ...; } } 

如果角色与“ADMIN”不同的用户访问该服务,我想将响应消息更改为类似的内容(取决于媒体类型[xml / json]):

  Not allowed.  

目前泽西岛返回以下机构:

 HTTP Status 403 - Forbidden type Status report message Forbidden description Access to the specified resource (Forbidden) has been forbidden. Apache Tomcat/7.0.12 

如何更改默认邮件正文? 有没有办法处理(可能抛出)exception来构建我自己的HTTP状态响应?

处理此类事情的最简单方法是抛出exception并注册exception映射器以转换为在这种情况下要发送的消息类型。 因此,假设你抛出一个AccessDeniedException ,你就会有一个像这样的处理程序(为了清楚起见,在地方有完整的类名):

 @javax.ws.rs.ext.Provider public class AccessDeniedHandler implements javax.ws.rs.ext.ExceptionMapper { public javax.ws.rs.core.Response toResponse(AccessDeniedException exn) { // Construct+return the response here... return Response.status(403).type("text/plain") .entity("get lost, loser!").build(); } } 

注册exception映射器的方式因您使用的框架而异,但对于Jersey,只需使用@Provider 。 我会让你自己弄清楚你想要如何生成你想要的那种错误文档,但是我建议把失败当作某种HTTP错误代码来处理(那更加RESTful …)

通过创建ExceptionMapper (映射WebApplicationExceptionexception),可以“捕获”应用程序抛出的某些exception:

 @Provider public class MyExceptionMapper implements ExceptionMapper { @Override public Response toResponse(WebApplicationException weException) { // get initial response Response response = weException.getResponse(); // create custom error MyError error = ...; // return the custom error return Response.status(response.getStatus()).entity(error).build(); } } 

您还需要将包添加到应用程序web.xml以注册提供程序:

  com.sun.jersey.config.property.packages  com.myapp.userservice; // semi-colon seperated com.myapp.mappedexception   

REST是基于HTTP构建的,因此您无需更改身份validation失败的默认行为。 访问资源时出现403错误足以让客户端清楚地了解附加内容。

您的资源越符合HTTP,其他人就越了解它。