简体   繁体   English

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

[英]Custom HTTP status response with JAX-RS (Jersey) and @RolesAllowed

With my very simple JAX-RS service I'm using Tomcat with JDBC realm for authentication, therefore I'm working the the JSR 250 annotations. 使用我非常简单的JAX-RS服务,我使用Tomcat和JDBC领域进行身份验证,因此我正在使用JSR 250注释。

The thing is that I want to return a custom message body in the HTTP status response. 问题是我想在HTTP状态响应中返回自定义消息体。 The status code (403) should stay the same. 状态代码(403)应保持不变。 For example, my service looks like the following: 例如,我的服务如下所示:

@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 ...;
    }
}

If a user with a different role than "ADMIN" access the service, I want to change the response message to something like that (depending on the media type [xml/json]): 如果角色与“ADMIN”不同的用户访问该服务,我想将响应消息更改为类似的内容(取决于媒体类型[xml / json]):

<error id="100">
    <message>Not allowed.</message>
</error>

At the moment Jersey returns the following body: 目前泽西岛返回以下机构:

HTTP Status 403 - Forbidden

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

How can I change the default message body? 如何更改默认邮件正文? Is there a way to handle the (maybe thrown) exception to build my own HTTP status response? 有没有办法处理(可能抛出)异常来构建我自己的HTTP状态响应?

The easiest way to handle this sort of thing is to throw an exception and to register an exception mapper to convert into the kind of message you want to send in that case. 处理此类事情的最简单方法是抛出异常并注册异常映射器以转换为在这种情况下要发送的消息类型。 So, suppose you throw an AccessDeniedException , you would then have a handler like this (with full class names in places for clarity): 因此,假设你抛出一个AccessDeniedException ,你就会有一个像这样的处理程序(为了清楚起见,在地方有完整的类名):

@javax.ws.rs.ext.Provider
public class AccessDeniedHandler
        implements javax.ws.rs.ext.ExceptionMapper<AccessDeniedException> {
    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();
    }
}

The way in which you register the exception mapper varies according to the framework you're using, but for Jersey you should be fine with just using @Provider . 注册异常映射器的方式因您使用的框架而异,但对于Jersey,只需使用@Provider I'll let you figure out for yourself how you want to generate the kind of error documents that you want, but I do recommend handling failures as HTTP error codes of some kind (that's more RESTful...) 我会让你自己弄清楚你想要如何生成你想要的那种错误文档,但我建议将失败处理为某种类型的HTTP错误代码(这更加RESTful ......)

With creating an ExceptionMapper (mapping exceptions of WebApplicationException ) it is possible to "catch" certain exceptions thrown by the application: 通过创建ExceptionMapper (映射WebApplicationException异常),可以“捕获”应用程序抛出的某些异常:

@Provider
public class MyExceptionMapper implements ExceptionMapper<WebApplicationException> {

    @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();
    }
}

You also need to add the package to your application web.xml for registering the provider: 您还需要将包添加到应用程序web.xml以注册提供程序:

<init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>
        com.myapp.userservice; // semi-colon seperated
        com.myapp.mappedexception
    </param-value>
</init-param>

REST is build upon HTTP so you don't have to change the default behavior of an authentication failure. REST是基于HTTP构建的,因此您无需更改身份验证失败的默认行为。 Having a 403 error when accessing a resource is enough for the client to clearly understand what appends. 访问资源时出现403错误足以让客户端清楚地了解附加内容。

The more your resources are HTTP compliant, the more others can understand it. 您的资源越符合HTTP,其他人就越了解它。

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

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