博客
关于我
Java,SpringBoot,全局异常处理,容器、404异常全局统一处理
阅读量:738 次
发布时间:2019-03-21

本文共 5866 字,大约阅读时间需要 19 分钟。

全局异常处理是Spring Boot应用中非常重要的一部分,能够统一处理各种异常,提升应用的健壮性和用户体验。本文将详细介绍Spring Boot全局异常处理的配置与实现,包括代码设计和优化。

全局异常处理概述

在Spring Boot应用中,通过@ControllerAdvice注解和配置文件application.yml,可以实现全局异常处理的统一配置。这种方法能够处理@Controller@RestController以及容器级别的异常,提升应用的异常处理能力。

异常处理逻辑设计

首先,我们需要定义一个通用的运行时异常BusinessException。该类应携带错误代码和错误信息,便于在全局处理器中构造返回结果。

package com.what21.demo.common;import lombok.Data;@Datapublic class BusinessException extends RuntimeException {    private Integer code;    private String message;    public BusinessException(String message) {        super(message);    }    public BusinessException(String message, Throwable cause) {        super(message, cause);    }    public BusinessException(Throwable cause) {        super(cause);    }    public BusinessException(Integer code, String message) {        super(code + ":" + message);        this.code = code;        this.message = message;    }}

接下来,创建封装返回结果的R类:

package com.what21.demo.common;import lombok.Getter;import lombok.Setter;import lombok.ToString;import java.io.Serializable;@Getter@Setter@ToStringpublic class R
implements Serializable { private static final long serialVersionUID = 1L; public static final String OK = "SUCCESS"; public static final String ERROR = "ERROR"; @Getter @Setter private String code; @Getter @Setter private String msg; @Getter @Setter private T data; public static
R
ok() { return instance(OK, null, null); } public static
R
ok(T data) { return instance(OK, null, data); } public static
R
ok(T data, String msg) { return instance(OK, msg, data); } public static
R
okMsg(String msg) { return instance(OK, msg, null); } public static
R
error() { return instance(ERROR, null, null); } public static
R
error(T data) { return instance(ERROR, null, data); } public static
R
error(T data, String msg) { return instance(ERROR, msg, data); } public static
R
errMsg(String msg) { return instance(ERROR, msg, null); } public static
R
instance(String code, String msg, T data) { R
result = new R<>(); result.setCode(code); result.setMsg(msg); result.setData(data); return result; }}

最后,配置全局异常处理器:

package com.what21.demo.common;import lombok.extern.slf4j.Slf4j;import org.springframework.validation.BindException;import org.springframework.validation.ObjectError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.servlet.NoHandlerFoundException;import java.util.List;@Slf4j@ControllerAdvicepublic class GlobalExceptionHandler {    @ExceptionHandler(value = {BusinessException.class})    @ResponseBody    public R businessExceptionHandler(BusinessException e) {        log.debug("处理业务异常,代码:{},信息:{}", e.getCode(), e.getMessage());        return R.instance(e.getCode().toString(), e.getMessage(), null);    }    @ExceptionHandler(value = {Exception.class})    @ResponseBody    public R exceptionHandler(Exception e) {        if (e instanceof NoHandlerFoundException) {            return R.instance("1001", e.getMessage(), null);        } else if (e instanceof IllegalArgumentException) {            return R.instance("1001", e.getMessage(), null);        } else if (e instanceof IllegalStateException) {            return R.instance("1001", e.getMessage(), null);        } else if (e instanceof BindException) {            BindException ex = (BindException) e;            List
allErrors = ex.getAllErrors(); ObjectError error = allErrors.get(0); return R.instance("1001", error.getDefaultMessage(), null); } else if (e instanceof MethodArgumentNotValidException) { MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e; List
errors = ex.getBindingResult().getAllErrors(); if (!errors.isEmpty()) { org.springframework.web.bind.BinderResult error = errors.get(0); return R.instance("1001", error.getDefaultMessage(), null); } } return R.instance("1001", e.getMessage(), null); }}

配置文件application.yml

spring:  mvc:    throw-exception-if-no-handler-found: true  resources:    add-mappings: false

测试案例

创建一个测试控制器:

package com.what21.demo.controller;import com.what21.demo.common.BusinessException;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class EchoController {    @GetMapping("/")    public String index(Model model) {        model.addAttribute("index", "首页");        return "index";    }    @RequestMapping(path = "/echo", method = {RequestMethod.GET})    @ResponseBody    public String echo() {        if (true) {            throw new BusinessException(1002, "业务异常信息");        }        return "hello";    }}

测试结果分析

通过上述配置,可以实现对以下场景的异常处理:

  • 业务异常:任何抛出的BusinessException都会被businessExceptionHandler捕获,并返回一个JSON格式的错误结果。

  • 未映射的URL异常:当URL未找到时,NoHandlerFoundException会导致返回一个格式化的404错误。

  • 参数验证异常@Valid注解和校验器 Butt师傅异常会被处理为标准化的错误信息。

  • 通过R.instance方法,可以根据不同场景构造特定的返回结果,实现JSON格式的错误处理。例如,R.instance(ERROR, "错误代码", "错误信息")将返回一个{error: "错误信息"}的JSON对象。

    性能优化与扩展

  • 减少重复代码:可以创建一个自定义的异常处理结果构建器,减少R.instance方法的重复调用。

  • 分区处理异常:根据异常类型分区处理,实现更细致的错误信息构建。

  • 日志记录:通过Slf4j或其他日志框架记录异常处理日志,方便定位问题。

  • 统一错误页面:可以通过редirect到一个统一的错误页面,提升用户体验。

  • 定制返回结果:根据需要扩展R类,添加更多的处理逻辑,使其适应不同业务需求。

  • 通过以上配置和实现,可以大大简化异常处理逻辑,使代码更加整洁高效,提升应用的稳定性和用户体验。

    转载地址:http://zhprz.baihongyu.com/

    你可能感兴趣的文章
    mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
    查看>>
    Webpack 基本环境搭建
    查看>>
    mysql5.7 安装版 表不能输入汉字解决方案
    查看>>
    MySQL5.7.18主从复制搭建(一主一从)
    查看>>
    MySQL5.7.19-win64安装启动
    查看>>
    mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
    查看>>
    MySQL5.7.37windows解压版的安装使用
    查看>>
    mysql5.7免费下载地址
    查看>>
    mysql5.7命令总结
    查看>>
    mysql5.7安装
    查看>>
    mysql5.7性能调优my.ini
    查看>>
    MySQL5.7新增Performance Schema表
    查看>>
    Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
    查看>>
    Webpack 之 basic chunk graph
    查看>>
    Mysql5.7版本单机版my.cnf配置文件
    查看>>
    mysql5.7的安装和Navicat的安装
    查看>>
    mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
    查看>>
    Mysql8 数据库安装及主从配置 | Spring Cloud 2
    查看>>
    mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>