java 捕获所有异常并返回 Jersey 中的自定义错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26796363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:37:15  来源:igfitidea点击:

Catch all Exceptions and also return custom Errors in Jersey

javajerseyjax-rsjersey-2.0

提问by Dominic

I want to catch all unexpected Exceptions in a jersey rest service. Therefore i wrote an ExceptionMapper:

我想在球衣休息服务中捕获所有意外的异常。因此我写了一个ExceptionMapper:

@Provider
public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> {
    private static Logger logger = LogManager.getLogManager().getLogger(ExceptionMapper.class.getName());

    @Override
    public Response toResponse(Exception e) {
        logger.log(Level.SEVERE, e.getMessage(), e);

        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal error").type("text/plain").build();
    }
}

The mapper catches really all exceptions. Therefore i can't write:

映射器确实捕获了所有异常。因此我不能写:

public MyResult getById(@PathParam("id")) {
    if (checkAnyThing) {
        return new MyResult();
    }
    else {
        throw new WebApplicationException(Response.Status.NOT_FOUND);
    }
}

This is catched by the Mapper. Now i have to write:

这是由 Mapper 捕获的。现在我必须写:

public Response getById(@PathParam("id") {
    if (checkAnyThing) { {
        return Response.ok().entity(new MyResult()).build();
    }
    else {
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}

Is this the correct way to catch all unexpected exceptions and also return errors (error codes) in jersey? Or is there any other (more correct) way?

这是捕获所有意外异常并在球衣中返回错误(错误代码)的正确方法吗?或者还有其他(更正确的)方法吗?

回答by Paul Samsotha

WebApplicationExceptionhas a getResponsefrom which we can get the Response. So you can check for a WebApplicationExceptionin your mapper. Maybe something like

WebApplicationException有一个getResponse我们可以从中得到Response. 因此,您可以WebApplicationException在映射器中检查 a 。也许像

@Override
public Response toResponse(Throwable error) {
    Response response;
    if (error instanceof WebApplicationException) {
        WebApplicationException webEx = (WebApplicationException)error;
        response = webEx.getResponse();
    } else {
        response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity("Internal error").type("text/plain").build();
    }
    return response;
}

That way an instance of WebApplicationExceptionthrown will just return the default response. This will actually handle some other exceptions also, not thrown explictly by your application. WebApplicationExceptionhas a few other exception under its hierarchy that are thrown by JAX-RS, for which predefined response/status codes are wrapped.

这样, throw 的实例WebApplicationException只会返回默认响应。这实际上也将处理一些其他异常,而不是由您的应用程序明确抛出。WebApplicationException在其层次结构下还有一些其他异常,这些异常由 JAX-RS 抛出,为其包装了预定义的响应/状态代码。

Exception                      Status code    Description
-------------------------------------------------------------------------------
BadRequestException            400            Malformed message
NotAuthorizedException         401            Authentication failure
ForbiddenException             403            Not permitted to access
NotFoundException              404            Couldn't find resource
NotAllowedException            405            HTTP method not supported
NotAcceptableException         406            Client media type requested 
                                                            not supported
NotSupportedException          415            Client posted media type 
                                                            not supported
InternalServerErrorException   500            General server error
ServiceUnavailableException    503            Server is temporarily unavailable 
                                                            or busy

That being said, we could explicitly throw any of these exceptions in our code, just to give it more semantic value.

话虽如此,我们可以在我们的代码中明确抛出任何这些异常,只是为了赋予它更多的语义价值。

Generally speaking though, the example above may be unnecessary, unless you want to alter the response message/status code, as one can from the table above, the hierarchy of exceptions already have some general mapping. And in most cases, unexpected exceptions will already be mapped to InternalServerErrorException

不过一般来说,上面的例子可能是不必要的,除非你想改变响应消息/状态代码,正如从上表中可以看出的,异常的层次结构已经有了一些通用的映射。并且在大多数情况下,意外的异常已经被映射到InternalServerErrorException