美文网首页
SpringBoot配置全局异常处理

SpringBoot配置全局异常处理

作者: 不减肥到一百三不改名字 | 来源:发表于2021-12-22 11:43 被阅读0次

一、环境

  • jdk1.8
  • idea2018.2.2
  • maven3.5.3
  • mybatsi-plus3.4.1
  • mysql5.7

二、项目配置

  • pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yxl</groupId>
    <artifactId>yxl</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0</version>
    <modules>
        <module>yxl_project01</module>
    </modules>
    <name>yxl</name>
    <description>公共项目</description>

    <properties>
        <druid-version>1.2.6</druid-version>
        <mybatis-plus-version>3.4.1</mybatis-plus-version>
        <mysql-connector-version>8.0.23</mysql-connector-version>
        <lombok-version>1.18.18</lombok-version>
        <hutool-version>5.6.5</hutool-version>
        <httpcore-version>4.4.12</httpcore-version>

    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.6</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid-version}</version>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-version}</version>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok-version}</version>
            </dependency>

            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool-version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
                <version>${httpcore-version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>
  • 统一返回结果
package com.yxl.common.util;

import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
 * @Classname R
 * @Description TODO
 * @Date 2021-12-20 17:19
 * @Created by yxl
 */
public class R extends HashMap<String,Object> {
    private static final long serialVersionUID = 1L;

    public R(){
        put("code",0);
        put("msg","success");
    }

    public static R error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    }

    public static R error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }

    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }
}
  • controller
package com.yxl.project01.controller;

import com.yxl.common.util.R;
import com.yxl.project01.entity.User;
import com.yxl.project01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Classname UserController
 * @Description TODO
 * @Date 2021-12-20 17:14
 * @Created by yxl
 */
@RestController
@RequestMapping("/user")
public class UserController {

}
  • dao
package com.yxl.project01.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxl.project01.entity.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * @Classname UserMapper
 * @Description TODO
 * @Date 2021-12-20 17:10
 * @Created by yxl
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

}
  • entity
package com.yxl.project01.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

/**
 * @Classname User
 * @Description TODO
 * @Date 2021-12-20 17:07
 * @Created by yxl
 */
@Data
@TableName("tb_user")
public class User {

    @TableId
    private Long id;

    private String name;

    private Integer age;

    private Date birthday;

    private String icon;

    private Integer status;

    private String description;
}
  • service
package com.yxl.project01.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.yxl.project01.entity.User;

/**
 * @Classname UserService
 * @Description TODO
 * @Date 2021-12-20 17:11
 * @Created by yxl
 */
public interface UserService extends IService<User> {

}
  • serviceImpl
package com.yxl.project01.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxl.project01.dao.UserMapper;
import com.yxl.project01.entity.User;
import com.yxl.project01.service.UserService;
import org.springframework.stereotype.Service;

/**
 * @Classname UserServiceImpl
 * @Description TODO
 * @Date 2021-12-20 17:12
 * @Created by yxl
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
  • 启动类
package com.yxl.project01;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Classname yxlProject01Application
 * @Description TODO
 * @Date 2021-12-20 17:03
 * @Created by yxl
 */
@SpringBootApplication
@MapperScan("com.yxl.project01.dao")
public class yxlProject01Application {

    public static void main(String[] args) {
        SpringApplication.run(yxlProject01Application.class,args);
    }
}

三、全局异常处理配置

1.首先在controller中创建一个方法getException(),制造一个异常

import com.yxl.project01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Classname UserController
 * @Description TODO
 * @Date 2021-12-20 17:14
 * @Created by yxl
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getException")
    public R getException(){
        int a = 10;
        int b = 0;
        System.out.println(a/b);
        return R.ok();
    }
}

2.重启服务器

3.访问此url后,在控制台出现如下异常

java.lang.ArithmeticException: / by zero
    at com.yxl.project01.controller.UserController.getException(UserController.java:23) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.12.jar:5.3.12]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.54.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.54.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.12.jar:5.3.12]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.12.jar:5.3.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.12.jar:5.3.12]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.12.jar:5.3.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.12.jar:5.3.12]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.12.jar:5.3.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.54.jar:9.0.54]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

此异常为算术异常:即除数不能为0,当我们使用前后端分离开发的时候,需要返回给前端统一格式的结果,那我们就需要用到全局异常处理,并自定义异常返回结果了。

4.定义全局异常处理

1.新增GlobalExceptionHandler.class类并添加如下配置

package com.yxl.project01.exception;

import com.yxl.common.util.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * @Classname GlobalExceptionHandler
 * @Description TODO
 * @Date 2021-12-22 11:13
 * @Created by yxl
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ArithmeticException.class)
    public R arithmeticExceptionHandler(ArithmeticException e){
        return R.error(10001,e.getMessage());
    }
}

@RestControllerAdvice:将该类标记为全局异常处理类。
@ExceptionHandler(ArithmeticException.class):标记在方法上表示该方法捕获哪些异常,小括号的形参就是要捕获的异常类

我们使用{}Postman再次请求url,结果如下图:

idea控制台也没有错误信息了,如下:

2.为了统一声明管理状态码和返回消息,我们可以声明一个枚举类BizCodeEnume.class专门来管理,如下:

package com.yxl.common.exception;

/**
 * @Classname BizCodeEnum
 * @Description TODO
 * @Date 2021-12-22 11:29
 * @Created by yxl
 */
public enum BizCodeEnum {

    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    ARITHMETIC_EXCEPTION(10001,"算术异常"),;
    
    private int code;
    private String msg;

    private BizCodeEnum(int code,String msg){
        this.code = code;
        this.msg = msg;
    }

    public int getCode(){
        return code;
    }

    public String getMsg(){
        return msg;
    }
}

3、修改全局异常处理方法中的代码

package com.yxl.project01.exception;

import com.yxl.common.exception.BizCodeEnume;
import com.yxl.common.util.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * @Classname GlobalExceptionHandler
 * @Description TODO
 * @Date 2021-12-22 11:13
 * @Created by yxl
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ArithmeticException.class)
    public R arithmeticExceptionHandler(ArithmeticException e){
        return R.error(BizCodeEnume.ARITHMETIC_EXCEPTION.getCode(),BizCodeEnume.ARITHMETIC_EXCEPTION.getMsg());
    }
}

4、重启服务器后使用Postman访问url,结果如下:

相关文章

网友评论

      本文标题:SpringBoot配置全局异常处理

      本文链接:https://www.haomeiwen.com/subject/ydrqqrtx.html