Spring REST 的异常处理机制

后端开发如何通过Spring Data REST提升系统的容错能力 在现代分布式系统中,容错能力是衡量系统质量的重要指标之一。Spring Data REST作为Spring生态系统中的重要组件,为快速构建RESTful服务提供了强大支持。本文旨在深入探讨如何充分利用Spring Data REST的特性来提升系统的容错能力,确保服务在面对各种异常情况时仍能保持稳定运行。首先介绍Spring Data REST的核心概念和容错相关特性深入分析各种容错机制的实现原理通过实际代码示例展示具体实现方法探讨在微服务架构中的扩展应用总结最佳实践和未来发展趋势。 阅读详情

翻译自:
最近流行的前后端分离方法中,异常处理机制往往还是处于旧的MVC异常处理机制,很大的一个缺点就是没有给响应主体添加任何有效信息而返回给客户端,通常是要求客户端重定向到一个预先定义好的错误页面,这个不符合REST风格,此篇文章承前启后不仅概括了原有的MVC异常处理机制,也提出了新的REST异常处理机制。并且秉承了一贯的风格,每篇文章都配有可以实际应用的代码。这篇文章对我的帮助很大,所以也特别翻译过来,希望也能帮助到其他人。

文章共分为六个部分:

1. 概括

2. 通过controller的@ExceptionHandler实现异常处理

3. 通过HandlerExceptionResolve实现异常处理

4. 通过@ControllerAdvice实现异常处理(Spring 3.2及以上版本)

5. 关于spring security访问拒绝的处理

6. 小结

1 概括

这篇文章将讲述在Spring REST 程序中如何进行异常处理。我们将讨论Spring 3.2和4.x版本以后所推荐的异常处理方法,同时也会对更低版本的异常处理做一些介绍。

在Spring 3.2之前,主要有两种处理方法:HandlerExceptionResolver或者@ExceptionHandler。两种方法都存在明显的缺点。

3.2版本之后,我们有了新的注解@ControllerAdvice来解决前两种方法的不足。

所有这些都有一个共同点——它们很好地处理了关注的分离。应用程序可以正常地抛出异常来指示某种类型的失败,这些异常将被单独处理。


2 解决方法 1- Controller中的注解@ExceptionHandler

第一个方法我们会在Contoller中定义一个方法来处理异常,这个方法用@ExceptionHandler来注解

public class FooController{
    //...
    @ExceptionHandler({CustomException1.class,CustomException2.class })
    public void handleException() {
        //
    }
}

此方法有一个主要缺点——@ ExceptionHandler注释方法只对该特定控制器有效,而不是全局应用程序。当然,将它添加到每个控制器使得它不能很好地适用于一般的异常处理机制。              限制通常是通过让所有控制器扩展基本控制器类来实现的,然而,这对于应用程序来说可能是个问题,无论出于什么原因,控制器不能从这样的类扩展。例如,Controller可能已经扩展了其他的类,或者本身可能不能直接修改。

接下来,我们将研究解决异常处理问题的另一种方法——一个是全局的,不包括对现有构件(如Controllers)的任何更改。

3 解决方法 2 – 利用HandlerExceptionResolver

第二个解决方案是定义一个HandlerExceptionResolver——这将解决应用程序抛出的任何异常。它还将允许我们在REST API中实现统一的异常处理机制。

在进行自定义解析器之前,让我们先看看现有的实现方式。

  
  
  
  
  
  
  
  
  
 
 
  
  
  

3.1 ExceptionHandlerExceptionResolver

这个解析器是在Spring 3.1中引入的,并且在DispatcherServlet中默认启用。这实际上是前面介绍的@ExceptionHandler的核心组成部分。
3.2 DefaultHandlerExceptionResolver
这个解析器是在Spring 3中引入的,并且在DispatcherServlet中默认启用。它用于解决标准的Spring异常到其相应的HTTP状态代码,即客户端错误-4xx和服务器错误-5xx状态代码。下面是它处理的Spring异常的完整列表,以及如何将这些映射到状态代码。
HTTP状态代码
201 (Created). 
304 (Not Modified) 
BindException 400 (Bad Request)
ConversionNotSupportedException500 (Internal Server Error)
HttpMediaTypeNotAcceptableException 406 (Not Acceptable)
HttpMediaTypeNotSupportedException415 (Unsupported Media Type)
HttpMessageNotReadableException400 (Bad Request)
HttpMessageNotWritableException500 (Internal Server Error)
HttpRequestMethodNotSupportedException405 (Method Not Allowed)
MethodArgumentNotValidException    400 (Bad Request)
MissingServletRequestParameterException400 (Bad Request)
MissingServletRequestPartException400 (Bad Request)
NoSuchRequestHandlingMethodException404 (Not Found)
TypeMismatchException400 (Bad Request)

  

虽然它确实设置了响应的状态代码,但有一个限制是它不对响应的主体设置任何内容。而对于一个REST API——状态代码实际上是不足以提供给客户端的信息——响应也必须有一个主体,以便允许应用程序提供关于失败的附加信息。

这可以通过配置ModelAndView配置视图解析和渲染错误内容来解决,但是解决方案显然不是最优的——这就是为什么在Spring 3.2中可以使用更好的选项——我们将在本文后面的部分讨论。
3.3 ResponseStatusExceptionResolver

此解析器也在Spring3中引入,默认情况下在DispatcherServlet中启用。它的主要职责是使用在自定义异常上可用的@ ResponseStatus注释,并将这些异常映射到HTTP状态代码。             
这样的自定义异常看起来像:
@ResponseStatus(value = HttpStatus.NOT_FOUND)
publi class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException() {
        super();
    }
    public ResourceNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }
    public ResourceNotFoundException(String message) {
        super(message);
    }
    public ResourceNotFoundException(Throwable cause) {
        super(cause);
    }
}


与DefaultHandlerExceptionResolver一样,这个解析器在处理响应体时受到限制——它在响应上映射状态代码,但是响应主体仍然是空的。

3.4 SimpleMappingExceptionResolver andAnnotationMethodHandlerExceptionResolver

SimpleMappingExceptionResolver已经存在了相当长的时间——它来自旧的Spring MVC模型,与REST服务不太相关。它用于映射异常类名称以视图的名称。             AnnotationMethodHandlerExceptionResolver在Spring3中引入,通过@ ExceptionHandler注释来处理异常,但是Spring 3.2已被ExceptionHandlerExceptionResolver替代。

3.5 Custom HandlerExceptionResolver

DefaultHandlerExceptionResolver和ResponseStatusExceptionResolver解决程序的组合对于提供一个良好的错误处理机制对于Spring REST服务有很大的帮助。缺点是,正如前面提到的那样,没有控制响应主题内容。理想情况下,我们希望能够输出JSON或XML,这取决于客户端请求的格式(通过Accept报头)。 借此一点就可以创建一个新的自定义异常解决程序:

@Component
public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
 
    @Override
    protected ModelAndView doResolveException
      (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        try {
            if (ex instanceof IllegalArgumentException) {
                return handleIllegalArgument((IllegalArgumentException) ex, response, handler);
            }
            ...
        } catch (Exception handlerException) {
            logger.warn("Handling of [" + ex.getClass().getName() + "] 
              resulted in Exception", handlerException);
        }
        return null;
    }
 
    private ModelAndView handleIllegalArgument
      (IllegalArgumentException ex, HttpServletResponse response) throws IOException {
        response.sendError(HttpServletResponse.SC_CONFLICT);
        String accept = request.getHeader(HttpHeaders.ACCEPT);
        ...
        return new ModelAndView();
    }
}


这里要注意的一个细节是请求本身是可用的,因此应用程序可以考虑客户端发送的Accept报头的值。例如,如果客户端请求应用程序/JSON,那么,在错误情况下,应用程序仍然应该返回用应用程序/JSON编码的响应体。另一个重要的实现细节是返回一个ModelAndView——这是响应的主体,它将允许应用程序设置它所需的任何内容。              这种方法是一个一致的和易于配置的Spring REST异常处理机制。但是它有局限性:它与低级HtttpServletResponse响应交互,它适合使用ModelAndView的旧MVC模型——因此仍有改进的余地。

4 新的解决方法3 利用@ControllerAdvice (Spring 3.2 及以上版本)

Spring 3.2为新的@ControllerAdvice建议注释提供了全局@ ExceptionHandler的支持。这使得异常处理机制摆脱了旧的MVC模型,并且使用了响应实体以及@ ExceptionHandler的类型安全性和灵活性。

新的注释允许从以前多个分散的@ ExceptionHandler合并成单个的全局错误处理组件。              实际机制非常简单,但也非常灵活:

l  它允许完全控制响应的主体以及状态代码。

l  它允许对同一方法中的几个异常进行映射,以便一起处理。          

l  它很好地利用了新的REST响应实体响应。

l  这里要记住的一件事是将声明的异常与@ ExceptionHandler相匹配,使用异常作为方法的参数。如果这些不匹配,编译器不会提示编译错误——没有理由,而且Spring也不会提示编译错误。

l  但是,当异常在运行时实际抛出时,异常解析机制将失败:

5 在Spring Security中处理拒绝访问

当经过身份验证的用户试图访问他没有足够权限访问的资源时,访问被拒绝。

5.1 MVC – Custom Error Page自定义错误页面

<http>
    <intercept-url pattern="/admin/*" access="hasAnyRole('ROLE_ADMIN')"/>   
    ... 
    <access-denied-handler error-page="/my-error-page" />
</http>
And the Java configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/admin/*").hasAnyRole("ROLE_ADMIN")
        ...
        .and()
        .exceptionHandling().accessDeniedPage("/my-error-page");
}


当用户试图访问一个没有足够权限的资源时,它们将被重定向到“/My Error页面”。

5.2 自定义AccessDeniedHandler

接下来,让我们看看如何编写我们的自定义AccessDeniedHandler:

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
 
    @Override
    public void handle
      (HttpServletRequest request, HttpServletResponse response, AccessDeniedException ex) 
      throws IOException, ServletException {
        response.sendRedirect("/my-error-page");
    }
}


现在让我们使用 XML 配置来配置它:
<http>
    <intercept-url pattern="/admin/*" access="hasAnyRole('ROLE_ADMIN')"/> 
    ...
    <access-denied-handler ref="customAccessDeniedHandler" />
</http>


或使用java配置:

@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
 
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/admin/*").hasAnyRole("ROLE_ADMIN")
        ...
        .and()
        .exceptionHandling().accessDeniedHandler(accessDeniedHandler)
}


请注意,在我们的CustomAccessDeniedHandler中,我们可以通过重定向或显示自定义错误消息来自定义响应。

5.3 利用REST和方法的安全机制

最后,让我们看看如何处理方法级安全性@ PreAuthorize、@ PostAuthorize和@ Secure Access Denied。

当然,我们将使用前面讨论过的全局异常处理机制来处理新的Access。

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
 
    @ExceptionHandler({ AccessDeniedException.class })
    public ResponseEntity<Object> handleAccessDeniedException(Exception ex, WebRequest request) {
        return new ResponseEntity<Object>(
          "Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN);
    }
     
    ...
}


6 小结

本教程讨论了几种在Spring中实现RESTAPI的异常处理机制的方法,从旧的机制开始,并继续探讨Spring 3.2,以及4和4.1支持的新的机制。              

一如往常,本文中提供的代码(GITHUB)可以实际使用。这是一个基于Maven的项目,因此应该很容易导入和运行。



十一、学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现) 学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现) 阅读详情

相关推荐

【数字图像相关-OpenCorr学习笔记】Epipolar search原理+代码解析

OpenCorr是一个开源C++库,用于研究和开发数字图像相关(DIC)技术它提供了2D和立体声DIC的全功能模块,以及数字体积相关(DVC)。最近正在学习OpenCorr,为了更深层次地理解ICGN,我打算浅浅剖析Opencorr的代码,学习的过程中写下这篇学习笔记,以后忘记了还能回来看看。同时,作为一名在读研究生,希望能得到社区大佬的指点,以及跟同学们一起学习进步。这一期主要讲解Eipipolar search的原理,并且附上部分代码解析。

ywyywyy的博客 1356

SpringBoot项目rest接口的全局异常处理

物料准备:1.一个全局异常处理类2.一个自定义的通用业务异常类3.一个公共的返回体泛型类4.系统返回码枚举类。

ThinkPet 440

瑞芯微RK3506开发板Ethercat主站性能优化实战:从内核配置到微秒级延迟控制

本文详细介绍了在瑞芯微RK3506开发板上实现EtherCAT主站微秒级延迟控制的实战优化方案。核心在于部署Preempt-RT实时内核,并进行深度系统调优,包括CPU隔离、中断亲和性设置、内存锁定及电源管理调整。通过绕过Linux网络栈的专用驱动加载与配置,最终实现了稳定的高性能实时控制,满足工业自动化需求。

tcp8optimizer的博客 315

一文搞定 Spring Security 异常处理机制!

今天来和小伙伴们聊一聊 Spring Security 中的异常处理机制。在 Spring Security 的过滤器链中,ExceptionTranslationFilter 过滤器专门用来处理异常,在 ExceptionTranslationFilter 中,我们可以看到,异常被分为了两大类:认证异常和授权异常,两种异常分别由不同的回调函数来处理,今天就来和大家分享一下这里的条条框框。Spring Security 中的异常可以分为两大类,一种是认证异常,一种是授权异常。认证异常就是 Authentic

老男孩的架构路 1033

跟着团子学SAP PS:BOM和项目结构的联动-BOM Transfer CN33

关于项目中的物料组件挂接你需要了解的一点功能

Lucas1211的博客 2万+

OpenClaw的引导配置(onboard)流程

脚本安装的直接安装完到引导配置界面,其他安装方式还可以直接命令到配置。

supersolon的专栏 1324

SpringSecurity异常处理源码解析

SpringSecurity异常处理源码解析 异常处理主要是由ExceptionTranslationFilter完成的,而ExceptionTranslationFilter是由ExceptionHandlingConfigurer配置的,所以我们从ExceptionHandlingConfigurer开始解析 我们首先看ExceptionHandlingConfigurer的configure(Httpsecurity security)方法: @Override public void configu

HHoao的博客 1059

从JTAG到AS模式:一文搞懂EP4CE10E22C8N所有配置引脚(MSEL, nCONFIG, DATA0)的用法

本文深入解析EP4CE10E22C8N FPGA的配置引脚(MSEL, nCONFIG, DATA0)在不同模式下的使用方法,特别关注从JTAG到AS模式的切换要点。通过详细的配置模式对比、状态机分析和PCB布局建议,帮助开发者避免常见陷阱,提升FPGA配置成功率。

weixin_33713350的博客 319

国网SG-UAP 开发平台 RestExceptionResolver 错误解决方法

国网SG-UAP 开发平台 RestExceptionResolver 错误解决方法

dearbaba_8520的博客 922

BME688传感器原理图设计,已量产(环境传感器)

在便携式空气质量监测、可穿戴健康设备这类低功耗场景中,BME688 这类集成了 VOC、温湿度、气压的四合一 MEMS 传感器越来越受欢迎 —— 它体积小、功耗低,刚好匹配便携设备的需求。但这类小信号传感器对电源噪声、电平匹配的要求很细,今天结合实际项目里的一款 BME688 接口电路,聊聊硬件设计的关键细节。

不脱发的程序猿 514

Android 13 内置xapk安装包的方法

安装xapk 内置xapk

安卓兼职framework和app工程师的博客 223

Spring Boot REST 异常处理机制

例如,采用{"code": 400, "message": "参数无效", "details": [...]}的JSON格式,确保所有异常响应遵循相同的规范。异常处理是API开发中不可忽视的重要环节,良好的异常处理机制能提升系统的健壮性和用户体验。Spring Boot提供了强大的异常处理支持,帮助开发者高效管理API中的错误响应。完善的异常处理需要充分的测试验证。结合Spring Boot Test的切片测试功能,可以快速验证全局异常处理器是否按预期工作,确保异常逻辑覆盖率达到要求。

qbypda_283的博客 219

解锁IPG Photonics SmartWeld系统,开启焊接新时代

SmartWeld 系统是 IPG Photonics 研发的一款先进的激光焊接解决方案,它隶属于自动化激光焊接系统类别 ,但却凭借一系列创新技术和独特设计,在众多同类产品中脱颖而出。该系统基于 IPG 在光纤激光技术领域的深厚积累,融合了先进的光束控制、智能监测和自动化控制等技术,旨在为工业制造提供高效、精准且稳定的焊接工艺。与传统激光焊接系统相比,SmartWeld 系统的独特之处首先体现在其光束控制技术上。它能够精确地调整激光束的能量分布、光斑大小和形状 ,以适应不同材料和焊接工艺的需求。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1428

Spring中REST API实现异常处理机制的几种方法

本文将说明如何使用Spring为REST API实现异常处理。我们还将简要介绍历史背景,并查看不同版本引入的异常处理选项。在Spring 3.2之前,在Spring MVC应用程序中处理异常的两种主要方法是HandlerExceptionResolver或@ExceptionHandler注释。两者都有一些明显的缺点。从3.2开始,我们引入了@ControllerAdvice注释,以解决前两个解决方案的局限性,并在整个应用程序中促进统一的异常处理。

Clang’s Blog 476

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spring REST API异常处理机制

@ControllerAdvice @ExceptionHandler 实现方式 @ControllerAdvice @ControllerAdvice是一个@Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。 Spring4之前,@Controlle...

苏暖午后 714

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring MVC—拦截器,文件上传,中文乱码处理,Rest风格,异常处理机制

拦截器 文件上传 -中文乱码解决 rest风格 异常处理机制拦截器Spring MVC可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口,重写以下3个方法。 @Override public boolean preHandle(HttpServletRequest request, HttpServle

爱是与世界平行 1104

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

需要知道Spring Cloud中的异常处理的套路

异常在Java中有两种分类:       **Error**(OutOfMemoryError之类的我们自己程序无法处理的非常严重的错误,Java推荐不catch,让程序随之崩溃)       **Excepiton**(NullPointerException之类的并不致命的错误,Java觉得indicates conditions that a reasonable application m...

weixin_44048532的博客 1429

REST和RESTful风格框架

转载: https://blog.youkuaiyun.com/weixin_42049777/article/details/81131819 https://blog.youkuaiyun.com/intelrain/article/details/80449371 https://blog.youkuaiyun.com/aiyaya_/article/details/78209992

zlt的博客 1467

Spring的REST API异常处理

Spring的REST错误处理-异常处理 1、概述 本文将阐述如何使用REST API的spring实现异常处理。我们还将获得一下历史概述,并查看不同版本引入了那些新选项。 在spring3.2之前,在spring MVC应用程序中处理异常主要有两种方法:HandlerExceptionResolver或@ExceptionHandler注解,两者都有明显的缺点。从3.2开始,spring有了@ControllerAdvice批注,已解决前两个方案的局限性,并在整个应用中促进统一异常处理。现在Sprin

qq_35464899的博客 1691

Spring MVC学习(9)—项目统一异常处理机制详解与使用案例

基于最新Spring 5.x,详细介绍了Spring MVC项目的统一异常处理机制,比如@ExceptionHandler和容器错误页面。

终生学习践行者 3321

Spring REST异常处理(自定义错误信息)

本文辅助资源: github源码:https://github.com/baeldung-cn/exception-handling-for-rest-with-spring 同步视频:https://www.bilibili.com/video/BV1oT4y1L7Mt/ 参考原文:https://www.baeldung.com/exception-handling-for-rest-with-spring 在开始以前你可以点击此处以获取一份与本教程相同的初始化代码。 1. 概述 本文将给出几

zzhongcy的专栏 3769

CANN ops-transformer MiniMaxSparseAttentionSplitKv PyTorch 扩展:构建安装与 KV-Gather-Q 稀疏注意力 Prefill 实战

MiniMaxSparseAttentionSplitKv 是 CANN ops-transformer 仓库中面向 Prefill 阶段 Sparse Attention 的实验性算子,采用 KV-Gather-Q(split-KV)方案:以 KV block 为主轴分任务,同一 KV block 只加载一次,随后遍历所有选择该 block 的 Q token 计算 partial attent

gitblog_01198的博客 702

在Spring Boot框架下的Java异常处理(包含SLF4J日志记录)

你可以根据业务需求创建自定义异常类,通常继承自Exception或。1.5.1 继承Exception类创建一个受检异常类,调用者需要处理它。1.5.2 继承类创建一个非受检异常类,不强制要求调用者处理。throw new CustomUncheckedException("值不能为负数");Exception和是Java异常体系的核心。受检异常必须捕获或声明,非受检异常可以选择处理。是处理异常的主要机制,finally用于资源释放。throws用于声明方法可能抛出的异常。可以通过继承。

m0_73837751的博客 1716

【转】REST风格框架实战:从MVC到前后端分离(附完整Demo)

版权声明:欢迎转载,注明作者和出处就好!如果不喜欢或文章存在明显的谬误,请留言说明原因再踩哦,谢谢,我也可以知道原因,不断进步! https://blog.youkuaiyun.com/justloveyou_/article/details/74379479 摘要:   本人在前辈《从MVC到前后端分离(REST-个人也认为是目前比较流行和比较好的方式)》一文的基础上,实现了一个基于Sprin...

weixin_30325487的博客 89
上一篇: Spring MVC 参数传递方式后端代码汇总
下一篇: Spring MVC 应用架构经典之路
java_augur
博客等级 码龄22年 67粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值