spring全局异常处理类ExceptionHandler获取request入参

解锁新技能《springboot全局异常处理@ExceptionHandler如何获取控制器方法上的注解》 springboot全局异常处理通常都是用@RestControllerAdvice标注异常处理类,使用@ExceptionHandler标注在捕获具体异常的方法上,我们可以通过异常参数获取异常信息,那如果我想获取抛出异常的具体控制器及其上面标注的注解如何获取呢? 阅读详情
AI摘要

文章讲述了在Spring项目中,如何使用ContentCachingRequestWrapper解决Controller中全局异常处理时,由于request.InputStream被读取导致无法获取请求体的问题,以及如何处理不同类型的异常并记录相关信息。

背景

项目中需要用到的数据校验、异常捕获,所以会用@ExceptionHandler方法,对Controller做统一的全局异常处理。当发生异常时,需要记录异常的url、入参、出参、错误信息等。但是request的inputStream已经读取过一次,此时拿到的request是空的。

解决方法

Spring提供了一个ContentCachingRequestWrapper,用于缓存从输入流读取出来的内容。我们可以在过滤器(Filter)中,将HttpServletRequest包装成ContentCachingRequestWrapper,这样后续就可以重复获取到请求体内容了。

定义RequestWrapperFilter

@Component
public class RequestWrapperFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(new ContentCachingRequestWrapper(httpServletRequest), httpServletResponse);
    }
}

修改GlobalExceptionHandler

@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    public static final String SERVICE_EXCEPTION = "order_exception";
    /**
     * 声明要捕获的异常
     */
    @ExceptionHandler({BindException.class,
            MethodArgumentNotValidException.class,
            GlobalException.class,
            Exception.class})
    @ResponseBody
    public <T> BaseResponse<T> handleException(Exception e) {
        BaseResponse<T> baseResponse;
        if (e instanceof BindException) {
            baseResponse = handle(((BindException) e).getBindingResult());
        } else if (e instanceof MethodArgumentNotValidException) {
            baseResponse = handle(((MethodArgumentNotValidException) e).getBindingResult());
        } else if (e instanceof GlobalException) {
            HttpError httpError = ((GlobalException) e).getHttpError();
            baseResponse = ResponseUtils.fail(httpError.getCode(), httpError.getMessage());
        } else {
            baseResponse = ResponseUtils.fail(OrderHtapResultEnum.SYSTEM_ERROR.getCode(), "系统异常:" + e);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.error("handleException catch exception!url:{},request:{},response:{},error:{}", request.getRequestURI(), JSON.toJSONString(getRequestBody(request)), baseResponse, e);
        MetricsApi.getInstance().reportCounter(SERVICE_EXCEPTION, 1);
        return baseResponse;
    }
    //重点是这里
    private static String getRequestBody(HttpServletRequest request) {
        ContentCachingRequestWrapper requestWrapper =
                WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
        if (requestWrapper == null) {
            return "";
        }
        return new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
    }


    private <T> BaseResponse<T> handle(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("verifyParams error --> " + bindingResult.toString());
            FieldError fieldError = bindingResult.getFieldError();
            return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), OrderHtapResultEnum.PARAM_ERROR.getMessage() + "(" + fieldError.getField() + ":" + fieldError.getDefaultMessage() + ")");
        }
        return ResponseUtils.fail(OrderHtapResultEnum.PARAM_ERROR.getCode(), OrderHtapResultEnum.PARAM_ERROR.getMessage());
    }
}

这里只适合post,put调用的方法,get调用的获取不到。

游程理论提取灾害事件特征V2---基于MATLAB语言的编程实现 游程理论,灾害事件,MATLAB 阅读详情

相关推荐

学习STM32的无人机控制

设计并实现无人机控制系统,使用STM32单片机进行控制。无人机控制系统主要包括飞行控制、姿态控制、定位导航等功能。以下是一个基于STM32的无人机控制系统的代码案例。以上是一个基于STM32的无人机控制系统的代码案例,包括飞行控制、姿态控制和定位导航等功能。请根据实际情况进行修改和完善。

qq_67153941的博客 837

【Spring】全局异常处理中,如何获取请求体内容?

SpringMVC项目中,将HttpServletRequest包装成ContentCachingRequestWrapper,可以实现对请求体内容的重复获取。这点在全局异常处理中很实用。

Season-0209的博客 2104

【AI开源】Understand-Anything 完整使用教程(2026最新版)

Understand-Anything是一款基于交互式知识图谱的AI学习与开发平台,能够将代码库转化为可视化知识结构,支持语义搜索、上下文问答和全流程开发。核心功能包括代码知识图谱化、AI辅助学习和多编码代理集成。支持TypeScript/JavaScript、Python等多种语言,要求Node.js 20+和16GB以上内存。提供NPM、Docker和源码三种安装方式,支持增量更新和团队知识共享。与同类产品相比,在交互式图谱、语义搜索和AI集成方面更具优势。适用于代码学习、大型项目维护和团队协作等场景。

与时俱进,开放共享 7199

发生异常时,从ExceptionHandler中获取Body参数进行分析

用SpringMVC时,使用ExceptionHandler去做Controller层的统一异常处理。 使用ExceptionHandler注解的异常处理方法可以使用很灵活的方法签名。 如何在异常发生时输出请求 发生异常时,不仅仅需要输出异常本身,经常还需要根据Request的具体内容来分析、排查问题。 比如HttpRequestMethodNotSupportedException、HttpMessageConversionException等等,这些异常发生在业务代码处理之前,业务代码是无法获取到req

H的博客 5694

GSM的“时间管理大师”:TDMA时隙、突发脉冲与逻辑信道映射实战图解

本文深入解析GSM网络中的TDMA时隙调度与逻辑信道映射技术,揭示2G网络如何通过精密的时间管理和突发脉冲设计实现高效通信。从TDMA帧结构到GMSK调制优化,详细介绍了GSM的工程艺术及其在现代通信中的延续价值。

weixin_30631587的博客 514

scratch航天梦主题课程作品分享,包含ppt、素材包

而今年多国都将发射探测器尝试登陆月球,2023年或将称为“登月年”,请大家发挥创新思维,以“星辰大海”为创作主题,搜集相关信息 、展开联想,为实现升空 、探测 、取样贡献创意!即使去淘宝买的素材,也要从百度网盘,但素材太多大了或者太多文件,也要充值百度网盘超级会员才能保存,提高下载速度。同学们大家好,今天我们就要开始航天主题-嫦娥五号探月工程系列的编程课程了,不仅可以学习到很多航天知识,了解本次嫦娥五号的发射历程,还能让我们用编程遨游太空呢。即使下载了,也要上传,不是特别方便,尤其是不好查找。

少儿编程吕口口 2480

SpringMVC ExceptionHandler原理与入参以及返回值

文章目录源码 & 原理入参与返回值 源码 & 原理 https://juejin.cn/post/6844903815859322893 Spring 入参与返回值 https://blog.youkuaiyun.com/j510924/article/details/51130853?ops_request_misc=%7B%22request%5Fid%22%3A%22163100093516780264072172%22%2C%22scm%22%3A%2220140713.130102334..%

weixin_38370441的博客 2325

嵌入式通信协议----Wi-Fi协议详解(一)

Wi-Fi,又称“无线网络”,是Wi-Fi联盟的商标,一个基于IEEE 802.11标准的无线局域网技术。“Wi-Fi”常写作“WiFi”或“Wifi”,但是这些写法并没有被Wi-Fi联盟认可。Wi-Fi产品经由Wi-Fi联盟的一家独立授权测试实验室进行严格测试,产品成功通过测试后,授予制造商或销售商使用Wi-Fi标志、Wi-Fi CERTIFIED标志和相关商标,Wi-Fi联盟使用术语“Wi-Fi CERTIFIED”来称呼这类通过认证的产品。

聪聪的成长之路 1655

互联网应用主流框架整合【Spring MVC异常处理机制】

【附源码】任何成熟的MVC框架都提供异常处理机制,当然可以在 Controller的请求处理方法中手动使用try…catch块捕捉异常,当捕捉到特定异常时,返回特定逻辑视图名,但这种处理方式非常烦琐,需要在请求处理方法中书写大量的catch块 最大的缺点还在于异常处理与代码 耦合,一旦需要改变异常处理方式,必须修改大量代码,如下代码所示

一块大洋 2万+

诊断数据库ODX标准协议ISO22901定义组成部分

综上所述,简略描述了ODX数据库中UML/XML/Text/Check rules具体功能以及详细内容。

Soly_kun的博客 907

Happycapy深度解析:AI智能体的“iPhone时刻“来了?

从理论到实践深度解析了融合OpenClaw和ClaudeCode优点的超强智能体工具Happycapy

program哲学 457

Spring全局异常

最近做一个spring微服务,当请求进入接口后,一旦发生错误,服务就会抛出异常,但是这个异常不是我们封装的,有时候跑出的信息我们想统一处理。例:如果是客户请求数据错误应该报出400的HttpStatus.BAD_REQUEST。但是由于这个错误是我们内部抛出的他还是会自动抛500,而且服务有很多接口,我们管理也不方便。所以需要一个全局的异常处理。如请求数据错误。@Data如JDBC链接超时。@Data定义自定义的统一管理的细致的error code。

TGO-Ming 1502

手把手教你学PCIE(2.1.23)--PCIe基本概念:链路速率协商

链路速率协商是一个多步骤的过程,确保发送端和接收端之间的链路速率设置一致。通过初始化链路速率寄存器、发送和接收 TS2 序列、检测链路对端的存在、交换链路速率信息、确定最大链路速率和配置链路速率,可以确保 PCIe 设备之间的数据传输速度最大化,从而提高数据传输效率。初始化链路速率寄存器:设置支持的最大链路速率。发送和接收 TS2 序列:检测链路对端的存在。交换链路速率信息:发送和支持的最大链路速率。确定最大链路速率:选择最小值作为最终链路速率。配置链路速率:更新链路速率寄存器。

MHD0815的博客 1815

在Spring Boot项目中使用全局异常处理

接着上一篇在Spring Boot项目中使用统一返回结果一文中,继续添加全局异常处理部分。

pikcacho_pkq的博客 2060

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

如何在Spring的ExceptionHandler中获取Body

目前是用SpringMVC时,往往使用ExceptionHandler去做Controller层的统一异常处理。 使用ExceptionHandler注解的异常处理方法可以使用很灵活的方法签名。 可使用的参数类型 一个异常参数。声明一个一般性的异常或者更加具体的异常 Request 和/或 response 对象(Servlet API 或 Portlet API)。可以选择一个特定 - request/response的类型,比如ServletRequest / HttpServletRequest

liuqinen的博客 825

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

SpringBoot自定义全局异常处理器

Springboot框架提供两个注解帮助我们十分方便实现全局异常处理器以及自定义异常。或(推荐)定义类,拦截所有异常。注解使得你可以在中处理异常,注解用于将指定异常绑定到处理的函数上。如下使用即对所有异常进行捕获处理。@Slf4jlog.error("系统异常{}", e.getMessage(),e);String errMessage = "系统异常";@Data事实上,写到这里已经可以用了,用来承载错误信息到前端,因为已经包含了。继承异常类写一个自定义的异常类。

m0_51390969的博客 1900

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Spring Boot:轻松设置全局异常处理

在全局异常处理器中,我们可以自定义异常响应的格式。在上面的代码中,我们创建了一个ApiError类来表示异常响应。这个类包含了HTTP状态码、错误消息和异常对象。// 省略getter和setter方法通过自定义异常响应,我们可以向客户端提供更丰富的错误信息,从而帮助他们更好地理解和解决问题。在Spring Boot中设置全局异常处理是一项非常重要的任务。通过使用注解和注解,我们可以轻松地创建一个全局异常处理器来捕获并处理应用中抛出的所有异常。

德乐懿的博客 2158

【SpringBoot】全局异常处理类

通过全局异常处理,可以:1. 统一处理各种异常,返回友好的错误信息。2. 提升系统的健壮性和用户体验。3. 根据项目需求扩展更多的异常处理逻辑。

aystl_gss的博客 718

全局异常处理@ExceptionHandler

全局异常处理器

qq_62532254的博客 1637

spring boot 对请求进行全局异常处理

个人认为:如果不使用全局异常处理的话,那么会有很多异常都需要使用try catch进行捕获,重复代码增加,增加代码的恶心程度。 controller层代码: @RestController @RequestMapping(value = "/user") public class UserController { @Resource private UserService userService; @GetMapping(value = "get") pu.

路西法Lucifer 861

SpringBoot 解决request请求体只能被读一次的问题,在全局异常@RestControllerAdvice ExceptionHandler中打印参数

request.getInputStream()获取请求body里面的内容只能被获取一次,ContentCachingRequestWrapper通过这个类能够解决解决HttpServletRequest inputStream只能读取一次的问题,但是这个类有缺陷(前提必须是doFilter之前不能使用request.getInputStream()方法)全局异常捕获类中打印异常POST请求的参数。在全局异常捕获类中使用。

TOP丶Chen 1926

Spring Boot全局异常处理终极指南:打造优雅的API错误响应体系

/ 异常基类@Data// 业务异常 - 400 Bad Request// 资源未找到异常 - 404 Not Found// 认证授权异常 - 401 Unauthorized// 服务异常 - 500 Internal Server ErrorSpring Boot的全局异常处理机制为开发者提供了一套完整、灵活的解决方案。分层处理:按照异常类型和处理优先级进行分层设计统一响应:标准化错误响应格式,提升API一致性国际化支持。

用文字记录技术,用分享回馈社区,用坚持见证成长 1593

ExceptionHandler注解使用

在上面的示例中,我们使用了@RestControllerAdvice注解来创建一个全局的异常处理器。然后,我们使用@ExceptionHandler注解来定义两个处理方法,分别处理Exception和CustomException类型的异常。当这些异常发生时,Spring会自动调用相应的处理方法,并返回一个响应实体。通过将该注解添加到方法上,你可以将该方法与特定类型的异常关联起来,以便在异常发生时自动调用该方法。如果应用于类上,则该类中的所有方法都可以处理异常。如果应用于方法上,则只有该方法可以处理异常。

小郭的博客 952

深入理解 Spring Boot Web 开发中的全局异常统一处理机制

本文深入探讨了Spring Boot中全局异常处理机制的核心原理与实现方法。通过分析传统异常处理的弊端,引出使用@ControllerAdvice和@ExceptionHandler实现统一异常处理的解决方案。文章详细介绍了标准错误响应体的定义、全局异常处理器的构建方法,以及自定义业务异常的实现方案。重点展示了如何通过集中式管理来避免代码冗余、保证响应格式统一,并提高系统可维护性。同时给出了生产环境中处理常见异常类型的代码示例,包括参数校验异常、空指针异常等,最后提供了一个兜底的未知异常处理方案,确保系统健

刘一说的IT专栏 1307

随笔 全局异常处理spring @ExceptionHandler

为了避免每次都try..catry,采用全局异常处理 请求: @PostMapping("/login") public String login(String password,String username) throws Exception{ int i=1/0; } 全局异常处理类: @RestControllerAdvice public class MyException { @ExceptionHandler(Excepti

全场梦游c的博客 334

Spring Boot 中的全局异常处理

文章目录8.1 定义返回的统一 JSON 结构8.2 处理系统异常8.2.1 处理参数缺失异常8.2.2 处理空指针异常8.2.3 一劳永逸?8.3 拦截自定义异常8.3.1 定义异常信息8.3.2 拦截自定义异常 在项目开发过程中,不管是对底层数据库的操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。如果对每个过程都单独作异常处理,那系统...

taojin12的博客 1126
上一篇: canal通过rocketMq同步数据延迟delay问题优化
下一篇: 接口数据脱敏实现方案
bxp1321
博客等级 码龄17年 146粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值