dubbo~全局异常拦截器的使用与设计缺陷

dubbo · 浏览次数 : 13

小编点评

本文介绍了JAX-RS中的ExceptionMapper接口及其在处理异常时的优先级和选择。为实现自定义异常,我们创建了一个DbViolationExceptionMapper类,并在spring配置中注册。在业务代码中,我们抛出自定义异常,并通过异常处理器返回相应的HTTP响应。 1. **异常处理重要性与优先级**:本文首先提到,JAX-RS 使用 ExceptionMapper 接口来将 Java 异常映射到 HTTP 响应。为实现自定义异常,我们创建了 UniqueException 类,并通过实现 ExceptionMapper 接口来自定义异常处理。 2. **实现ExceptionMapper接口**:在文章中,我们看到了 DbViolationExceptionMapper 的实现,该类对应于一个自定义的异常类型——DbViolationException。在这个类中,我们重写了 toResponse(Exception ex) 方法以处理特定类型的异常,并生成相应的 HTTP 响应。请注意,如果有多个 Exception Mapper 可用于处理同一类型的异常,JAX-RS 会选择最具体的那个。例如,处理 NullPointerExcetion 的.mapper 覆盖会优先于处理 RuntimeException 的mapper。 3. **注册ExceptionMapper**:为了使自定义异常处理器的功能生效,我们在应用程序的配置文件中添加了刚刚实现的DbViolationExceptionMapper。这样,当出现 UniqueException 时,JAX-RS 会使用这个异常处理器来处理并返回适当的 HTTP 响应。 4. **业务代码中的异常抛出与日志记录**:示例代码展示了如何抛出自定义的 UniqueException 异常,并在业务代码中捕获该异常。同时,我们可以看到如何在一个过滤器中设置状态码和响应头,从而影响返回给客户的 HTTP 响应格式。 5. **状态码为200时的响应类型**:文章中指出,当异常处理器返回的 Response 对象的状态码为 200 时,响应类型应为 "application/json"。这是为什么我们可以在 toResponse 方法中指定 "application/json" 类型的原因。 6. **排版归纳总结**:最后,文章总结了异常处理的重要性、优先级和选择机制,以及如何自定义 ExceptionMapper 和注册到 Spring Boot 应用程序中。同时也指出了业务代码中的异常抛出、日志记录以及在过滤器中控制响应头设置的排版方式。 总之,本文详细解释了JAX-RS中使用ExceptionMapper接口来处理自定义异常的方法和步骤,包括实现 ExceptionMapper 接口、注册自定义异常处理器、异常在业务代码中的抛出和处理,以及如何控制状态码和响应类型。

正文

异常拦截器ExceptionMapper

在JAX-RS(Java API for RESTful Web Services)中,ExceptionMapper接口用于将Java异常映射到HTTP响应。通过实现ExceptionMapper接口,你可以自定义如何处理特定类型的异常,并生成相应的HTTP响应。

优先级和选择

当有多个ExceptionMapper可用于处理同一类型的异常时,JAX-RS会选择最具体的那个。例如,如果你有一个处理RuntimeException的ExceptionMapper和一个处理NullPointerException的ExceptionMapper,那么当抛出NullPointerException时,会选择处理NullPointerException的ExceptionMapper。

定义自定义异常

    public class UniqueException extends RuntimeException {

	public UniqueException(Throwable cause) {
		super(cause);
	}

	public UniqueException(String message) {
		super(message);
	}

	public UniqueException(String message, Throwable cause) {
		super(message, cause);
	}

}

实现ExceptionMapper

/**
 * 数据表约束异常处理器.
 *
 * @author lind
 * @date 2024/6/4 10:45
 * @since 1.0.0
 */
@Provider
public class DbViolationExceptionMapper implements ExceptionMapper<UniqueException> {

	@Override
	public Response toResponse(UniqueException exception) {

		return Response.status(Response.Status.BAD_REQUEST)
				.entity(MapUtil.builder().put("error", exception.getMessage()).build()).type(MediaType.APPLICATION_JSON)
				.encoding("utf-8").build();// 非200的请求,这个type无效,一直是text/plain

		/*
		 * return Response.status(Response.Status.OK)
		 * .entity(MapUtil.builder().put("error", exception.getMessage()).build())
		 * .type("application/json; charset=UTF-8").build();//
		 * 200的请求,是可以使用application/json的
		 *
		 */
	}

}

注册ExceptionMapper

在文件resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports添加内容

com.xx.exception.handler.DbViolationExceptionMapper

业务代码直接抛出异常

if (getCurrentUserId() == null || !getCurrentUserId().equals(userId)) {
	throw new UniqueException("权限不足");
 }

相关问题

  • 当在ExceptionMapper中返回的Response对象,状态码为200时,可以响应为application/json
  • 当Response对象状态码非200时,响应一直是text/plain

经过调试与排查,发现当非200时,在这个过滤器里,它出现了两个content-type,text/plain不知道是什么时间被加进去的,如图

方法执行到这里时,为响应头添加了text/plain

setStatus()方法如下

  public void setStatus(int status) {
        if (status > 200) {
            this.addOutputHeaders(RestHeaderEnum.CONTENT_TYPE.getHeader(), MediaType.TEXT_PLAIN.value);
        }

        this.status = status;
    }

这也是业务代码中,直接报出自定义异常,在ExceptionMapper捕获返回json没有生效的原因,这块感觉dubbo设计的不太好。

与dubbo~全局异常拦截器的使用与设计缺陷相似的内容:

dubbo~全局异常拦截器的使用与设计缺陷

异常拦截器ExceptionMapper 在JAX-RS(Java API for RESTful Web Services)中,ExceptionMapper接口用于将Java异常映射到HTTP响应。通过实现ExceptionMapper接口,你可以自定义如何处理特定类型的异常,并生成相应的HTT

dubbo~全局异常拦截器的使用与设计缺陷~续

上一次的介绍,主要围绕如何统一去捕获异常,以及为每一种异常添加自己的Mapper实现,并且我们知道,当在ExceptionMapper中返回非200的Response,不支持application/json的响应类型,而是写死的text/plain类型。 Filter为二方包异常手动捕获 参考:ht

深入理解java和dubbo的SPI机制

1 SPI简介 1.1 SPI(Service Provider Interface) 本质:将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。 java SPI:用来设计给服务提供商做插件使用的。基于策略模式来实现动态加载的机制。我

Spring Cloud微服务核心架构分析

Spring Cloud是一个相对比较成熟的微服务框架。虽然,Spring Cloud于2016年才推出1.0的release版本, 时间最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分布式系统解决方案。 Spring Cloud是一系列框架的有序集合。它利用Spri

面试官:Dubbo一次RPC请求经历哪些环节?

大家好,我是三友~~ 今天继续探秘系列,扒一扒一次RPC请求在Dubbo中经历的核心流程。 本文是基于Dubbo3.x版本进行讲解 一个简单的Demo 这里还是老样子,为了保证文章的完整性和连贯性,方便那些没有使用过的小伙伴更加容易接受文章的内容,这里快速讲一讲Dubbo一个简单的Demo 如果你已

哈啰面试:说说Dubbo运行原理?

Dubbo 是一款高性能、轻量级的开源 RPC(远程过程调用)框架,主要用于构建分布式服务和微服务架构。那 Dubbo 又是如何运行的呢?让我们一起来看。 1.核心组件 要说 Dubbo 运行流程就不得不先来了解一下 Dubbo 的核心组件了,因为 Dubbo 的交互流程是和核心组件息息相关的。 D

dubbo~javax.validation和jakarta.validation的介绍与排雷

javax.validation和jakarta.validation都是用于Java中进行数据验证(validation)的相关API,它们提供了一套标准的验证框架,用于验证Java对象的属性是否符合指定的约束条件。这两个API的作用类似,只是在Java EE平台的演进过程中发生了一些变化。 ja

Dubbo 中 Zookeeper 注册中心原理分析

本文通过分析Dubbo中ZooKeeper注册中心的实现ZooKeeperResitry的继承体系结构,详细介绍了Dubbo中ZooKeeper注册中心的实现原理。

Dubbo架构设计与源码解析(一) 架构设计

作者:黄金 一、架构演变 单应用架构 > 垂直架构 > 分布式架构 > 微服务架构 > 云原生架构   二、Dubbo总体架构   1、角色职能 • Container:服务容器 (tomcat、jetty、weblogic) • Provider:服务提供者 •Consumer:服务消

Dubbo架构设计与源码解析(三)责任链模式

作者:周可强 一、责任链模式简介 1、责任链模式定义 责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。