当您使用JAX-RS创建REST服务时,通常要么不返回任何内容(例如HTTP 201/2/4等),要么返回某些数据(可能采用JSON格式(因此HTTP 200),或者返回某些异常/错误(例如HTTP 4xx或5xx) )。
我们通常将运行时异常转换为某些HTTP 5xx,将已检查异常转换为某些4xx。
因为我们要保持边界整洁,所以当我们将Exception转换为HTTP响应时,我们不会在响应的主体中包含完整的Java stacktrace。 我们通常只添加带有HTTP 5xx(有时是4xx)响应的“ REASON”标头。 但是,这意味着我们的大多数ExceptionMappers看起来都差不多(类似这样):
@Providerpublic class SomeExceptionMapper implements ExceptionMapper<SomeException> {@Overridepublic Response toResponse(SomeException exception) {return Response.status(500).header("reason", exception.getMessage()).build();}}
使用MicroProfile Config API
我们可以使用MicroProfile Config API创建一个可配置的Exception Mapper,它允许使用者将Exception配置为HTTP响应代码映射。
我们的@Provider
将处理所有运行时异常:
@Providerpublic class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {// ...}
我们@ @Inject
配置和提供程序:
@Injectprivate Config config;@Context private Providers providers;
当我们实现toResponse
方法时,我们会在配置中查看此Exception类的映射:
@Override@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})public Response toResponse(RuntimeException exception) {return handleThrowable(exception);}private Response handleThrowable(Throwable exception) {if(exception instanceof WebApplicationException) {return ((WebApplicationException) exception).getResponse();}if(exception!=null){String configkey = exception.getClass().getName() + STATUS_CODE_KEY;Optional<Integer> possibleDynamicMapperValue = config.getOptionalValue(configkey,Integer.class);if(possibleDynamicMapperValue.isPresent()){int status = possibleDynamicMapperValue.get();// You switched it offif(status<0)return handleNotMapped(exception);String reason = getReason(exception);log.log(Level.FINEST, reason, exception);return Response.status(status).header(REASON, reason).build();} else if(exception.getCause()!=null && exception.getCause()!=null && providers!=null){final Throwable cause = exception.getCause();return handleThrowable(cause);} else {return handleNotMapped(exception);}}return handleNullException();}
( 这里有完整的示例)
我们还将向上处理异常链,直到获得映射,或者默认为正常的500错误。
因此,我们可以为映射添加配置,如下所示:
## 503 Service Unavailable: The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException/mp-jaxrs-ext/statuscode=503## 401 Unauthorized (RFC 7235): Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.javax.ws.rs.NotAuthorizedException/mp-jaxrs-ext/statuscode=401
在上面的示例中,我们将CircuitBreakerOpenException(来自MicroProfile容错API)映射到503,将NotAuthorizedException映射到401。
屏幕截图示例
用作库。
您还可以将所有这些捆绑在一个jar文件中,以供您的任何项目使用。 我在maven Central和github中提供了上述内容,因此您也可以直接使用它。
只需将其添加到您的pom.xml
<dependency><groupId>com.github.phillip-kruger.microprofile-extensions</groupId><artifactId>jaxrs-ext</artifactId><version>1.0.9</version></dependency>
它带有一些预定义的映射,但是您可以在配置中覆盖它。
翻译自: https://www.javacodegeeks.com/2018/08/jax-rs-exceptionmapper-config.html