zoukankan      html  css  js  c++  java
  • Spring Boot 系列教程6-全局异常处理

    @ControllerAdvice源码

    package org.springframework.web.bind.annotation;
    
    import java.lang.annotation.Annotation;
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.core.annotation.AliasFor;
    import org.springframework.stereotype.Component;
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface ControllerAdvice {
    
        @AliasFor("basePackages")
        String[] value() default {};    
        @AliasFor("value")
        String[] basePackages() default {};
        Class<?>[] basePackageClasses() default {};
        Class<?>[] assignableTypes() default {};
        Class<? extends Annotation>[] annotations() default {};
    
    }

    源码说明

    @ ControllerAdvice是一个@ Component,
    用于定义@ ExceptionHandler的,@InitBinder和@ModelAttribute方法,适用于所有使用@ RequestMapping方法,并处理所有@ RequestMapping标注方法出现异常的统一处理

    项目图片

    这里写图片描述

    pom.xml

    <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.jege.spring.boot</groupId>
        <artifactId>spring-boot-controller-advice</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>spring-boot-controller-advice</name>
        <url>http://maven.apache.org</url>
    
        <!-- 公共spring-boot配置,下面依赖jar文件不用在写版本号 -->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.1.RELEASE</version>
            <relativePath />
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <!-- web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- 持久层 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <!-- h2内存数据库 -->
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <!-- 测试 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <!-- 只在test测试里面运行 -->
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
        <build>
            <finalName>spring-boot-controller-advice</finalName>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    CommonExceptionAdvice.java

    package com.jege.spring.boot.exception;
    
    import java.util.Set;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.ConstraintViolationException;
    import javax.validation.ValidationException;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.dao.DataIntegrityViolationException;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.validation.BindException;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.FieldError;
    import org.springframework.web.HttpMediaTypeNotSupportedException;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.MissingServletRequestParameterException;
    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.ResponseStatus;
    
    import com.jege.spring.boot.json.AjaxResult;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:全局异常处理
     */
    @ControllerAdvice
    @ResponseBody
    public class CommonExceptionAdvice {
    
      private static Logger logger = LoggerFactory.getLogger(CommonExceptionAdvice.class);
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(MissingServletRequestParameterException.class)
      public AjaxResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        logger.error("缺少请求参数", e);
        return new AjaxResult().failure("required_parameter_is_not_present");
      }
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(HttpMessageNotReadableException.class)
      public AjaxResult handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("参数解析失败", e);
        return new AjaxResult().failure("could_not_read_json");
      }
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(MethodArgumentNotValidException.class)
      public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("参数验证失败", e);
        BindingResult result = e.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        return new AjaxResult().failure(message);
      }
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(BindException.class)
      public AjaxResult handleBindException(BindException e) {
        logger.error("参数绑定失败", e);
        BindingResult result = e.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        return new AjaxResult().failure(message);
      }
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(ConstraintViolationException.class)
      public AjaxResult handleServiceException(ConstraintViolationException e) {
        logger.error("参数验证失败", e);
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        ConstraintViolation<?> violation = violations.iterator().next();
        String message = violation.getMessage();
        return new AjaxResult().failure("parameter:" + message);
      }
    
      /**
       * 400 - Bad Request
       */
      @ResponseStatus(HttpStatus.BAD_REQUEST)
      @ExceptionHandler(ValidationException.class)
      public AjaxResult handleValidationException(ValidationException e) {
        logger.error("参数验证失败", e);
        return new AjaxResult().failure("validation_exception");
      }
    
      /**
       * 405 - Method Not Allowed
       */
      @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
      @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
      public AjaxResult handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("不支持当前请求方法", e);
        return new AjaxResult().failure("request_method_not_supported");
      }
    
      /**
       * 415 - Unsupported Media Type
       */
      @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
      @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
      public AjaxResult handleHttpMediaTypeNotSupportedException(Exception e) {
        logger.error("不支持当前媒体类型", e);
        return new AjaxResult().failure("content_type_not_supported");
      }
    
      /**
       * 500 - Internal Server Error
       */
      @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
      @ExceptionHandler(ServiceException.class)
      public AjaxResult handleServiceException(ServiceException e) {
        logger.error("业务逻辑异常", e);
        return new AjaxResult().failure("业务逻辑异常:" + e.getMessage());
      }
    
      /**
       * 500 - Internal Server Error
       */
      @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
      @ExceptionHandler(Exception.class)
      public AjaxResult handleException(Exception e) {
        logger.error("通用异常", e);
        return new AjaxResult().failure("通用异常:" + e.getMessage());
      }
    
      /**
       * 操作数据库出现异常:名称重复,外键关联
       */
      @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
      @ExceptionHandler(DataIntegrityViolationException.class)
      public AjaxResult handleException(DataIntegrityViolationException e) {
        logger.error("操作数据库出现异常:", e);
        return new AjaxResult().failure("操作数据库出现异常:字段重复、有外键关联等");
      }
    }
    
    

    ServiceException.java

    package com.jege.spring.boot.exception;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:自定义异常类
     */
    public class ServiceException extends RuntimeException {
      public ServiceException(String msg) {
        super(msg);
      }
    }
    
    

    Application.java

    package com.jege.spring.boot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:spring boot 启动类
     */
    
    @SpringBootApplication
    public class Application {
    
      public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
      }
    
    }
    

    不需要application.properties

    AdviceController

    package com.jege.spring.boot.controller;
    
    import java.util.List;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.jege.spring.boot.exception.ServiceException;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:全局异常处理演示入口
     */
    @RestController
    public class AdviceController {
    
      @RequestMapping("/hello1")
      public String hello1() {
        int i = 1 / 0;
        return "hello";
      }
    
      @RequestMapping("/hello2")
      public String hello2(Long id) {
        String string = null;
        string.length();
        return "hello";
      }
    
      @RequestMapping("/hello3")
      public List<String> hello3() {
        throw new ServiceException("test");
      }
    }
    

    访问

    源码地址

    https://github.com/je-ge/spring-boot

    如果觉得我的文章对您有帮助,请予以打赏。您的支持将鼓励我继续创作!谢谢!
    微信打赏
    支付宝打赏

  • 相关阅读:
    转载个人认为原创很不错的分析 :ISCSI网络存储
    使用centos-vault作为停止支持的CentOS的yum源
    AngularJS 第四课(选择框,HTML DOM,HTML 事件)
    AngularJS第三课(控制器(续),过滤器,服务)
    AngularJS第二课(指令,作用域,控制器)
    Angular.js学习笔记——第一课 简介
    简单的响应式表格布局
    在windows sever2012安装web服务器时出现“无法打开运行空间池。服务器管理器 WinRM 插件可能已损坏或丢失”
    HTML5中的全局属性
    href="#"和href="javascript:void(0)"的区别
  • 原文地址:https://www.cnblogs.com/je-ge/p/6107133.html
Copyright © 2011-2022 走看看