具有MicroProfile配置的可配置JAX-RS ExceptionMapper

当您使用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看起来都差不多(类似这样):

@Provider
    public class SomeExceptionMapper implements ExceptionMapper<SomeException> {

        @Override
        public Response toResponse(SomeException exception) {
            return Response.status(500).header("reason", exception.getMessage()).build();
        }

    }

使用MicroProfile Config API

我们可以使用MicroProfile Config API创建一个可配置的Exception Mapper,它允许使用者将Exception配置为HTTP响应代码映射。

我们的@Provider将处理所有运行时异常:

@Provider
    public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
        // ...
    }

我们@ @Inject配置和提供程序:

@Inject
    private 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 off
                if(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 Centralgithub中提供了上述内容,因此您也可以直接使用它。

只需将其添加到您的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值