jersey返回码问题

45 阅读1分钟

项目中使用了jersey框架,使用过程中遇到一些问题,而网上关于jersey的资料比较少,花了一段时间看源码和官网才解决,记录下来,希望遇到同样问题的同学可以更快解决问题

Throws NotAuthorizedException,NotFoundException等但最终返回500错误

原因:jersey jar包中有对4xx,5xx返回码的默认处理类DefaultExceptionMapper,由于实际项目中自定义了DefaultExceptionMapper类,导致对404处理时找不到处理类,返回500 jersey包中的处理类判断异常中是否存在Response,如果存在直接返回。

class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
    @Override
    public Response toResponse(Throwable exception) {
        return (exception instanceof WebApplicationException)
                ? processWebApplicationException((WebApplicationException) exception)
                : processDefaultException(exception);
    }

    private static Response processWebApplicationException(WebApplicationException exception) {
        return (exception.getResponse() == null)
                ? processDefaultException(exception)
                : exception.getResponse();
    }

    private static Response processDefaultException(Throwable exception) {
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity(LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER())
                .build();
    }
}

解决办法: 自定义的DefaultExceptionMapper中,增加Response判断,或者自定义WebApplicationException处理类

@Provider
public class WebApplicationExceptionMapper implements ExceptionMapper<WebApplicationException> {
    /**
     * {@inheritDoc}
     */
    @Override
    public Response toResponse(WebApplicationException wae) {
        return (wae.getResponse() == null) ? callChainedMapper(wae.getCause()) : wae.getResponse();
    }

    protected <T extends Throwable> Response callChainedMapper(T wrappedException) {
        Response response;
        try {
            ExceptionMapper<T> mapper = (ExceptionMapper<T>) providers.getExceptionMapper(wrappedException.getClass());
            if (mapper != null && wrappedException != null) {
                response = mapper.toResponse(wrappedException);
                return response;
            }
        } catch (Exception e) {
            LOGGER.error("Failed to find exception mapper", wrappedException);
        }
        return buildUnexpectedResponse(wrappedException);
    }

    /**
     * * @return the unexpected Response with a 500.
     */
    @SuppressWarnings({"PMD.UnusedPrivateMethod"}) // PMD seems to think this method is unused. 
    private Response buildUnexpectedResponse(Throwable exception) {
        UnexpectedExceptionResource body = new UnexpectedExceptionResource(exception);
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(body).build();
    }
}

- Response 未设置默认entity,接口使用Response.status(Status.SERVICE_UNAVAILABLE).build()返回500错误码

原因: jersey server中,如果返回码非200,会优先sendError->查找对应error page,而实际项目中如果没有error page,最终会报500错误,与预期错误码不一致。jersey提供了配置以优先处理status而不是sendError,jersey.config.server.response.setStatusOverSendError 设置为true时优先处理status

解决办法: jersey增加配置,status覆盖sendError

config.addProperties(

        Map.of(

                JERSEY_LOGGER_LEVEL,loggerLevel,

                "jersey.config.server.response.setStatusOverSendError",true

        )

);

jersey官网 eclipse-ee4j.github.io/jersey.gith…