SpringBoot系列17-统一异常处理(包含简单的JSR303参数校验)

猿份哥 1月前 ⋅ 78 阅读 ⋅ 0 个赞

原文链接:https://www.lskyf.com/post/211

方法1.通过ControllerAdvice实现+简单的JSR303参数校验实现

1.1 加入依赖

<dependencies>
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-validation</artifactId>
      </dependency>
</dependencies>

1.2 校验Bean.java实现

/**
 * @author yuanfenge
 * @description
 * @createTime 2019 - 3 - 07 11:54
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Bean {

    @NotNull(message = "不能为空")
    private String name;

    @Min(value = 1, message = "大于0")
    @NotNull(message = "不能为空")
    private Integer age;
}

统一异常处理的ExceptionControllerAdvice.java

/**
 * @author yuanfenge
 * 方法1:异常处理
 */
@Slf4j
@ControllerAdvice
public class ExceptionControllerAdvice {

    /**
     * 已废弃:发现此方法已失效
     * 使用{@link ExceptionControllerAdvice#bindExceptionHandler(MethodArgumentNotValidException)}替代
     * 处理BindException异常
     * 获得参数和错误消息封装到map集合通过json返回
     * @param ex
     * @return
     * @throws Exception
     */
    @Deprecated
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Map<String, Object> bindExceptionHandler(BindException ex) throws Exception {
        String s = ex.getFieldError().getField() + ":" + ex.getFieldError().getDefaultMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", s);
        return map;
    }

    /**
     * 最新参数绑定异常
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Map<String, Object> bindExceptionHandler(MethodArgumentNotValidException ex) throws Exception {
        BindingResult result = ex.getBindingResult();
        StringBuilder s=new StringBuilder();
        if (result.hasErrors()) {

            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p ->{
                FieldError fieldError = (FieldError) p;
                s.append(fieldError.getField()+":"+fieldError.getDefaultMessage());
            });
        }
        Map<String,Object> map=new HashMap<>();
        map.put("code",400);
        map.put("msg",s);
        return map;
    }
    /**
     * 处理自定义的ParamException异常
     * 获得参数和错误消息封装到map集合通过json返回
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(ParamException.class)
    @ResponseBody
    public Map<String, Object> customExceptionHandler(ParamException ex) throws Exception {
        String msg = ex.getMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", msg);
        return map;
    }

    /**
     * 处理其他异常
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Map<String, Object> exceptionHandler(Exception ex) throws Exception {
        String msg = ex.getMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 500);
        map.put("msg", msg);
        return map;
    }
}

测试TestContorller.java


@RestController
public class TestContorller {

    @RequestMapping("/valid")
    public Object valid(@Valid Bean bean) throws ParamException, CustomException {
        customParamCheck(bean);
        //customException();//打开注释可以测试自定义异常处理代码
        runtimeException();
        return bean;
    }

    private void runtimeException() {
        int a = 1 / 0;
    }

    private void customParamCheck(@Valid Bean bean) throws ParamException {
        if (bean.getAge() > 100) {
            throw new ParamException("age不能超过100");
        }
    }

    private void customException() throws CustomException {
        throw new CustomException("customException!!!");
    }
}

方法2.通过继承BaseController实现


/**
 * 方法2:异常处理 其他controller继承BaseController即可
 */
public class BaseController {
    /**
     * 已废弃:发现此方法已失效
     * 使用{@link BaseController#bindExceptionHandler(MethodArgumentNotValidException)}替代
     * 处理BindException异常
     * 获得参数和错误消息封装到map集合通过json返回
     * @param ex
     * @return
     * @throws Exception
     */
    @Deprecated
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Map<String, Object> bindExceptionHandler(BindException ex) throws Exception {
        String s = ex.getFieldError().getField() + ":" + ex.getFieldError().getDefaultMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", s);
        return map;
    }

    /**
     * 最新参数绑定异常
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Map<String, Object> bindExceptionHandler(MethodArgumentNotValidException ex) throws Exception {
        BindingResult result = ex.getBindingResult();
        StringBuilder s=new StringBuilder();
        if (result.hasErrors()) {

            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p ->{
                FieldError fieldError = (FieldError) p;
                s.append(fieldError.getField()+":"+fieldError.getDefaultMessage());
            });
        }
        Map<String,Object> map=new HashMap<>();
        map.put("code",400);
        map.put("msg",s);
        return map;
    }

    @ExceptionHandler(ParamException.class)
    @ResponseBody
    public Map<String, Object> customExceptionHandler(ParamException ex) throws Exception {
        String msg = ex.getMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", msg);
        return map;
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Map<String, Object> customExceptionHandler(Exception ex) throws Exception {
        String msg = ex.getMessage();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 500);
        map.put("msg", msg);
        return map;
    }
}

源码下载链接

原文链接: https://www.lskyf.com/post/211

作者:猿份哥,版权所有,欢迎保留原文链接进行转载:)


全部评论: 0

    我有话说:

    Spring Boot系列2-全局统一异常处理

    原创: 天空和唯美 天空唯美  点击查看原文 为什么要全局统一异常处理呢?如果系统发生了异常,不做统一异常处理,前端会给用户展示一大片看不懂文字。做统一异常处理后当

    SpringBoot系列18-validation分组校验+自定义参数校验

    原文链接: https://www.lskyf.com/post/212 分组-加入依赖 <dependencies> <dependency> <groupId>org.springframework.boo...

    spring boot系列4-定时任务-springboot自带scheduled超级简单

    需求:创建一个每天凌晨0点执行定时任务1.创建任务 /** * @author 天空蓝蓝 */ @Slf4j @EnableScheduling @Component public class

    Spring Boot系列1-helloword

      使用springboot简单轻松创建helloword SpringBoot系列1-helloword 关于springboot这是摘自官方一段话 Spring Boot

    SpringBoot系列19-防止重复请求,重复表单提交超级简单注解实现之四(终极版II)

    前言: 根据最新spring boot:2.5.0版本和在《SpringBoot防止重复请求,重复表单提交超级简单注解实现之四(终极版I)》之上化繁为简抽取更实用代码,新增超时机制 防重复提交

    SpringBoot系列10-文件上传

    文章目录 1.先来最简单 2.设置文件大小,请求大小 3.多文件上传 怎样使用最简单方式上传文件,如何上传多个文件呢 先来最简单 pom.xml文件引入依赖文件 <

    SpringBoot系列15-mysql-multiple-data-sources1

    springboot 多数据源一个简单示例 多数据源分包加载 新建数据库test1和表tbl_user CREATE TABLE `tbl_user` ( `id` int(11) NOT

    Spring Boot系列7-SpringBoot+mybatis+druid+TypeHandler

    介绍在SpringBoot中集成mybatis和druid以及自定义TypeHandler 创建数据库表 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- --------------------...

    Spring Boot系列6-SpringBoot中使用servlet

    介绍在SpringBoot中如何使用servlet pom.xml <dependency> <groupId>org.springframework.boot<

    spring boot系列3-四步完成观察者事件发布接收(发送消息接收消息)使用异步方不阻塞主线程

    1.首先Application开启异步 @SpringBootApplication @EnableAsync public class DemoApplication { public

    【扩展程序】 100套简历模板打包送你,有工作收藏!没工作用上!各行各业都可以用最漂亮简历打动HR,愿你有一个好工作。希望你有一份好薪水。

    ​ 前言 100套简历模板打包送你,有工作收藏!没工作用上!各行各业都可以用最漂亮简历打动HR,愿你有一个好工作。愿你有一份好薪水。愿你天黑有灯,下雨有伞! 下面看看有哪些简历 0001

    Spring Boot系列5-定时任务-springboot整合quartz实现动态定时任务

    MyJob实现Job接口,重写execute方法在里面操作我们要执行业务逻辑。 @Slf4j public class MyJob implements Job { @Autowired

    Spring Boot系列8-使用jasypt加密配置文件内容简单

    加密内容是username和pwd 5.将加密...

    win10如何彻底关闭自动更新

    缘由:win10自动更新是默认开启,一有新版本就会提示更新,并且有时候更新会占用很长一段时间。如何彻底关闭自动更新呢? 方法:这里列举一个比较简单方法 1.键盘同时按下 【win+R】 打开

    加入公众号
    加入公众号