Поймать все Исключения, а также вернуть пользовательские ошибки в Джерси

Я хочу поймать все непредвиденные Исключения в службе трикотажа. Поэтому я написал 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();
    }
}

Перехватчик действительно выполняет все исключения. Поэтому я не могу написать:

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

Это отображается с помощью Mapper. Теперь я должен написать:

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

Это правильный способ поймать все неожиданные исключения, а также вернуть ошибки (коды ошибок) в трикотаж? Или есть другой (более правильный) способ?

Ответ 1

WebApplicationException имеет getResponse, из которого мы можем получить Response. Таким образом, вы можете проверить WebApplicationException в своем картографе. Может быть, что-то вроде

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

Таким образом, экземпляр 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

Говоря это, мы можем явно исключить любое из этих исключений в наш код, чтобы дать ему более семантическое значение.

В общем случае, приведенный выше пример может быть ненужным, если вы не хотите изменять ответное сообщение/код состояния, как можно из приведенной выше таблицы, иерархия исключений уже имеет некоторое общее сопоставление. И в большинстве случаев неожиданные исключения уже будут отображаться на InternalServerErrorException