SpringBoot统一异常处理和统一返回格式

这篇具有很好参考价值的文章主要介绍了SpringBoot统一异常处理和统一返回格式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上篇博客我们讲解了使用AOP来进行统一的用户登录判断,其实像这种功能统一且使用较多的地方,都可以用AOP来处理,除了统⼀的⽤户登录判断之外,AOP 还可以实现:

  • 统⼀⽇志记录
  • 统⼀⽅法执⾏时间统计(在性能优化阶段,监控流量,接口的响应时间等甚至每个方法的响应时间,为整个项目的性能进行优化)
  • 统⼀的返回格式设置 (对于接口的返回格式,基本上都是code,message,data)
  • 统⼀的异常处理
  • 事务的开启和提交等

1.统一异常处理

我们写一个类来测试一下:

package com.example.springaop.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
//@RequestMapping("/ex")
public class ExceptionController {
    @RequestMapping("/test1")
    public boolean test1() {
        int a = 10/0;
        return true;
    }

    @RequestMapping("/test2")
    public boolean test2() {
        String str = null;
        System.out.println(str.length());
        return true;
    }

    @RequestMapping("/test3")
    public boolean test3() {
        throw new RuntimeException("测试运行时异常");
    }
}

运行后去浏览器访问对于的url测试:

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

可以在控制台看见对应的异常信息如果不进行统一异常处理的话,那么有些浏览器可能会将异常清楚的告知用户 

统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表示控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执⾏某个通知,也就是执⾏某个⽅法事件,具体实现代码如下:
package com.example.springaop.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.HashMap;

@ControllerAdvice// 控制器的通知,交给Spring管理
public class ErrorHandler {
    @ResponseBody// 表示返回的数据不是视图
    @ExceptionHandler
    public Object error (Exception e) {// 根据我的方法参数来捕获异常,这里捕获的就是Exception异常
        HashMap<String, Object> result = new HashMap<>();
        result.put("success",0);
        result.put("code",-1);
        result.put("msg","内部异常");
        return result;
    }
}
  • ⽅法名和返回值可以⾃定义,其中最重要的是 @ExceptionHandler(Exception.class) 注解,括号里面的内容可以不写
  • 当有多个异常通知时,匹配顺序为当前类及其⼦类向上依次匹配
我们去浏览器测试一下异常
SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言 

可以看到这些异常返回了相应的结果 

我们再来写一个捕获算数异常和空指针异常统一处理的方法

    @ResponseBody// 表示返回的数据不是视图
    @ExceptionHandler
    public Object error (ArithmeticException e) {// 根据我的方法参数来捕获异常,这里捕获的就是算数ArithmeticException异常
        HashMap<String, Object> result = new HashMap<>();
        result.put("success",0);
        result.put("code",-2);
        result.put("msg","ArithmeticException。。。");
        return result;
    }

    @ResponseBody// 表示返回的数据不是视图
    @ExceptionHandler
    public Object error (NullPointerException e) {// 根据我的方法参数来捕获异常,这里捕获的就是空指针异常
        HashMap<String, Object> result = new HashMap<>();
        result.put("success",0);
        result.put("code",-3);
        result.put("msg","NullPointerException。。。");
        return result;
    }

此时我们再来访问算数异常的url为test1,空指针异常为test2

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言 

此时就返回了我们设置的算数异常和空指针异常应该返回的数据 

这里有一个需要注意的点就是,如果我们给ExceptionController加上了拦截器

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 这样我们再去访问的时候发现:

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言 

我们并未修改Exception Controller类中的任何代码,只是给他加了一个拦截器而已,那么这又是什么原因呢?

我们查看环绕通知的代码即可发现,不论是什么异常,经过环绕通知最后都变成了运行时异常

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

解决办法就是把这里修改一下,把连接点里面的异常直接抛出,就像下面这样:SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 此时我们再去浏览器测试:

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言 

算数异常和空指针异常又正常显示了

代码之间经常会互相影响,出现错误后,一定要有耐心的寻找错误,相信自己一定可以找到的

2.统⼀的返回格式

1. 为什么需要统⼀数据返回格式

  • ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。
  • 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就⾏了,因为所有接⼝都是这样返回的。
  • 有利于项⽬统⼀数据的维护和修改。
  • 有利于后端技术部⻔的统⼀规范的标准制定,不会出现稀奇古怪的返回内容

2. 统⼀数据返回格式的实现

统⼀的数据返回格式可以使⽤ @ControllerAdvice + ResponseBodyAdvice 的⽅式实现,具体实现代码如下:

 

@ControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice {

    /**
     * 内容是否需要重写(通过此⽅法可以选择性部分控制器和⽅法进⾏重写)
     * 返回 true 表示重写
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    /**
     * ⽅法返回之前调⽤此⽅法
     */
    @Override
    public Object beforeBodyWrite(Object body, // 响应的正文内容
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {
        // 封装
        HashMap<String, Object> result = new HashMap<>();
        result.put("success",1);
        result.put("data",body);
        result.put("errorMsg","");
        return result;
    }
}

此时我们在访问user类中的url:

/**
 * 用户需要调用的一些方法
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    // 获取用户信息
    @RequestMapping("/get")
    public String getInfo() {
        log.info("获取信息...");
        return "获取信息";
    }

    // 注册
    @RequestMapping("/reg")
    public Boolean reg() {
        log.info("注册...");
        return true;
    }

    // 登录
    @RequestMapping("/log")
    public Boolean log(HttpServletRequest request, String username, String password) {
        log.info("login...");
        // 判断用户名和密R码,如果有任意一个为空,那么就不能登陆成功
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return false;
        }
        // 此时判断用户名和密码是否正确
        // 假装判断一下
        if (!"admin".equals(username) || !"admin".equals(password)) {
            return false;
        }
        // 此时用户名和密码校验通过
        // 参数true表示,如果没有存放Session,那么需要创建一个Session来存放当前登录的用户
        HttpSession session = request.getSession(true);
        session.setAttribute("username",username);
        return true;
    }

}

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言 

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 可以看到,我们访问get的url时出错了,因为它返回的数据是String类型

原因在这里可以看到:SpringBoot 使用 beforeBodyWrite 实现统一的接口返回类型_一梦喂马.的博客-CSDN博客

那么该如何解决呢?

再加一个判断方法,当它返回的数据为String类型时,手动按照Json的数据格式返回

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 异常使用@SneakyThrows注解,重新去浏览器访问:

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

可以看到访问成功了,不论访问的是那个页面,成功与否,返回的数据都是我们刚才设置的统一格式

3.总结

  • 自定义拦截器使⽤ WebMvcConfigurer+ HandlerInterceptor来实现,
  • 统⼀异常处理使⽤ @ControllerAdvice + @ExceptionHandler 来实现,
  • 统⼀返回值处理使⽤@ControllerAdvice + ResponseBodyAdvice 来处理
下篇见~

 SpringBoot统一异常处理和统一返回格式,springboot,java,开发语言

 文章来源地址https://www.toymoban.com/news/detail-618228.html

到了这里,关于SpringBoot统一异常处理和统一返回格式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring Boot】拦截器与统一功能处理:统一登录验证、统一异常处理与统一数据返回格式

     Spring AOP是一个基于面向切面编程的框架,用于将横切性关注点(如日志记录、事务管理)与业务逻辑分离,通过代理对象将这些关注点织入到目标对象的方法执行前后、抛出异常或返回结果时等特定位置执行,从而提高程序的可复用性、可维护性和灵活性。但使用原生Sp

    2024年02月16日
    浏览(38)
  • Spring Boot 统一功能处理(拦截器实现用户登录权限的统一校验、统一异常返回、统一数据格式返回)

    目录 1. 用户登录权限校验 1.1 最初用户登录权限效验 1.2 Spring AOP 用户统⼀登录验证 1.3 Spring 拦截器 (1)创建自定义拦截器 (2)将自定义拦截器添加到系统配置中,并设置拦截的规则 1.4 练习:登录拦截器 (1)实现 UserController 实体类 (2)返回的登录页面:login.html (3)实

    2024年02月12日
    浏览(38)
  • 【Spring Boot统一功能处理】统一异常处理,统一的返回格式,@ControllerAdvice简单分析,即将走进SSM项目的大门! ! !

    前言: 大家好,我是 良辰丫 ,在上一篇文章中我们已经学习了一些统一功能处理的相关知识,今天我们继续深入学习这些知识,主要学习统一异常处理,统一的返回格式,@ControllerAdvice简单分析.💌💌💌 🧑个人主页:良辰针不戳 📖所属专栏:javaEE进阶篇之框架学习 🍎励志语句:生

    2024年02月16日
    浏览(36)
  • Springboot 中设置统一的返回格式

    在我们应用中我们通常与前端交互使用json 格式,设置统一的返回json 格式是非常必要的,可以减少开发人员的工作量。 第一个使用统一的消息转换器,这里使用jackson 的相关功能,引入jar 创建一个全局配置类(GlobalConfig)并使用 @Configuration 注解标记该类为配置类。然后,在

    2024年01月25日
    浏览(32)
  • Springboot 设置统一的请求返回格式

    现在开发过程中主要采用前后端分离的方式进行开发测试,也就是前端封装请求,后端提供标准的API接口服务。一般现在json 格式受到开发者们的青睐,学习过程中我们可以设置接口的返回类型,那么怎么做到设置统一的返回格式呢?以下是在项目开发过程中一般的模式标准

    2024年02月13日
    浏览(34)
  • SpringBoot统一收集异常信息并返回给前端

    目录 适用场景 实现方法 结合Servlet对象 @RestControllerAdvice 通常前后端交互时,后端对前端参数进行校验后,对于校验不通过的信息会自定义一个异常抛出,但是后端一旦抛出异常,后台接口服务就会报500的错误 对于有些逻辑错误而言,我们只是想将此信息提示给用户,这时候

    2023年04月08日
    浏览(34)
  • springboot全局统一返回处理

    项目中一般都会有规定好的接口返回格式,无论成功与失败,一般格式都是不变的,这样是为了方便前后端统一处理,今天就来说下前后端统一处理的较为优雅的方式; 一般而言都会有一个统一的返回类作为接口的返回数据的封装,例如: 然后我们通过此类作为返回参数的统一封装

    2024年02月13日
    浏览(34)
  • SpringBoot第14讲:SpringBoot 如何统一异常处理

    本文是SpringBoot第14讲,SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例, 如何优雅的将参数校验的错误信息统一处理并封装返回呢

    2024年02月11日
    浏览(36)
  • springboot 统一异常处理 + 日志记录

          在项目的开发中,在某些情况下,比如非业务的操作,日志记录,权限认证和异常处理等。我们需要对客户端发出的请求进行拦截,常用的API拦截方式有Fliter,Interceptor,ControllerAdvice以及Aspect。先简单介绍一下不同的拦截方式。 可以获得Http原始的请求和响应信息,

    2023年04月17日
    浏览(36)
  • SpringBoot 全局异常统一处理:BindException(绑定异常)

    在Spring Boot应用中,数据绑定是一个至关重要的环节,它负责将HTTP请求中的参数映射到控制器方法的入参对象上。在这个过程中如果遇到问题,如参数缺失、类型不匹配或验证失败等,Spring MVC将会抛出一个 org.springframework.validation.BindException 异常。本文将深入解析 BindExceptio

    2024年01月18日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包