项目中使用了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…