• 需求

    在构建RestFul的今天,我们一般会限定好返回数据的格式比如:

    {

    "code": 0,
      "data": {},
      "msg": "操作成功"

    }

    但有时却往往会产生一些bug。这时候就破坏了返回数据的一致性,导致调用者无法解析。所以我们常常会定义一个全局的异常拦截器。

    注意:ControllerAdvice注解 只拦截Controller 不回拦截 Interceptor的异常

  • 介绍

    在spring 3.2中,新增了@ControllerAdvice 注解,用于拦截全局的Controller的异常,注意:ControllerAdvice注解只拦截Controller不会拦截Interceptor的异常

  • 代码

    package com.cmc.schedule.handler;
    
    import com.gionee.base.entity.JsonResult;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.ConversionNotSupportedException;
    import org.springframework.beans.TypeMismatchException;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.HttpMessageNotWritableException;
    import org.springframework.web.HttpMediaTypeNotAcceptableException;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    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 java.io.IOException;
    
    /**
     * 异常拦截处理器
     *
     * @author chenmc
     */
    @ControllerAdvice
    @ResponseBody
    public class GlobalExceptionHandler {
    
        private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s";
        private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
        //运行时异常
        @ExceptionHandler(RuntimeException.class)
        public String runtimeExceptionHandler(RuntimeException ex) {
            return resultFormat(1, ex);
        }
    
        //空指针异常
        @ExceptionHandler(NullPointerException.class)
        public String nullPointerExceptionHandler(NullPointerException ex) {
            return resultFormat(2, ex);
        }
    
        //类型转换异常
        @ExceptionHandler(ClassCastException.class)
        public String classCastExceptionHandler(ClassCastException ex) {
            return resultFormat(3, ex);
        }
    
        //IO异常
        @ExceptionHandler(IOException.class)
        public String iOExceptionHandler(IOException ex) {
            return resultFormat(4, ex);
        }
    
        //未知方法异常
        @ExceptionHandler(NoSuchMethodException.class)
        public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
            return resultFormat(5, ex);
        }
    
        //数组越界异常
        @ExceptionHandler(IndexOutOfBoundsException.class)
        public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
            return resultFormat(6, ex);
        }
    
        //400错误
        @ExceptionHandler({HttpMessageNotReadableException.class})
        public String requestNotReadable(HttpMessageNotReadableException ex) {
            System.out.println("400..requestNotReadable");
            return resultFormat(7, ex);
        }
    
        //400错误
        @ExceptionHandler({TypeMismatchException.class})
        public String requestTypeMismatch(TypeMismatchException ex) {
            System.out.println("400..TypeMismatchException");
            return resultFormat(8, ex);
        }
    
        //400错误
        @ExceptionHandler({MissingServletRequestParameterException.class})
        public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
            System.out.println("400..MissingServletRequest");
            return resultFormat(9, ex);
        }
    
        //405错误
        @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
        public String request405(HttpRequestMethodNotSupportedException ex) {
            return resultFormat(10, ex);
        }
    
        //406错误
        @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
        public String request406(HttpMediaTypeNotAcceptableException ex) {
            System.out.println("406...");
            return resultFormat(11, ex);
        }
    
        //500错误
        @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
        public String server500(RuntimeException ex) {
            System.out.println("500...");
            return resultFormat(12, ex);
        }
    
        //栈溢出
        @ExceptionHandler({StackOverflowError.class})
        public String requestStackOverflow(StackOverflowError ex) {
            return resultFormat(13, ex);
        }
    
        //其他错误
        @ExceptionHandler({Exception.class})
        public String exception(Exception ex) {
            return resultFormat(14, ex);
        }
    
        private <T extends Throwable> String resultFormat(Integer code, T ex) {
            ex.printStackTrace();
            log.error(String.format(logExceptionFormat, code, ex.getMessage()));
            return JsonResult.failed(code, ex.getMessage());
        }
    
    }  
    package com.cmc.base.entity;
    
    import com.alibaba.fastjson.JSON;
    import lombok.Data;
    
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author chenmc
     * @date 2017/10/12 17:18
     */
    @Data
    public class JsonResult implements Serializable{
    
        private int code;   //返回码 非0即失败
        private String msg; //消息提示
        private Map<String, Object> data; //返回的数据
    
        public JsonResult(){};
    
        public JsonResult(int code, String msg, Map<String, Object> data) {
            this.code = code;
            this.msg = msg;
            this.data = data;
        }
    
        public static String success() {
            return success(new HashMap<>(0));
        }
        public static String success(Map<String, Object> data) {
            return JSON.toJSONString(new JsonResult(0, "解析成功", data));
        }
    
        public static String failed() {
            return failed("解析失败");
        }
        public static String failed(String msg) {
            return failed(-1, msg);
        }
        public static String failed(int code, String msg) {
            return JSON.toJSONString(new JsonResult(code, msg, new HashMap<>(0)));
        }
    
    }
    

    Spring Boot这样就可以了,如果是没用Spring Boot的话,需要在SpringMvc的配置文件中增加下面的配置

    <!-- 处理异常 -->
        <context:component-scan base-package="com.gionee.xo" use-default-filters="false">
    	    <!-- base-package 如果多个,用“,”分隔 -->
    	    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    	    <!--控制器增强,使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常-->
    	    <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
    	</context:component-scan>

Spring Boot @ControllerAdvice 处理全局异常,返回固定格式Json的更多相关文章

  1. 只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

    ## 统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生. 比较通用的返回值格式如下: ```jav ...

  2. 在Spring Boot中添加全局异常捕捉提示

    在一个项目中的异常我们我们都会统一进行处理的,那么如何进行统一进行处理呢? 全局异常捕捉: 新建一个类GlobalDefaultExceptionHandler, 在class注解上@Controll ...

  3. Spring Boot自定义Redis缓存配置,保存value格式JSON字符串

    Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...

  4. Spring Cloud Gateway过滤器精确控制异常返回(实战,完全定制返回body)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 Spring Cloud Gateway应用 ...

  5. Spring Boot2 系列教程(十三)Spring Boot 中的全局异常处理

    在 Spring Boot 项目中 ,异常统一处理,可以使用 Spring 中 @ControllerAdvice 来统一处理,也可以自己来定义异常处理方案.Spring Boot 中,对异常的处理有 ...

  6. Spring Cloud Gateway过滤器精确控制异常返回(实战,控制http返回码和message字段)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Spring Cloud Gat ...

  7. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  8. Spring Boot @ControllerAdvice+@ExceptionHandler处理controller异常

    需求: 1.spring boot 项目restful 风格统一放回json 2.不在controller写try catch代码块简洁controller层 3.对异常做统一处理,同时处理@Vali ...

  9. spring boot如何处理异步请求异常

    springboot自定义错误页面 原创 2017年05月19日 13:26:46 标签: spring-boot   方法一:Spring Boot 将所有的错误默认映射到/error, 实现Err ...

随机推荐

  1. javamail 发送、读取邮件

    概述 1.邮件相关的标准 厂商所提供的 JavaMail 服务程序可以有选择地实现某些邮件协议,常见的邮件协议包括: SMTP(Simple Mail Transfer Protocol) :即简单邮 ...

  2. Anconda 3.7安装以及使用详细教程

    Anconda 3.7安装以及使用详细教程 2019-04-17    22:42:03 一.下载anconda 3.7 链接地址:官方地址 二.安装 双击下载好的Anaconda3-2019.03- ...

  3. python 判断连个 Path 是否是相同的文件夹

    python 判断连个 Path 是否是相同的文件夹 import os os.path.normcase(p1) == os.path.normcase(p2) normcase() 在 windo ...

  4. vue-cli3.0安装element-ui组件及按需引入element-ui组件

    在VUE-CLI 3下的第一个Element-ui项目(菜鸟专用) (https://www.cnblogs.com/xzqyun/p/10780659.html) 上面这个链接是vue-cli3.0 ...

  5. Extjs小总结

    1.绑定工作流:    INSERT INTO `base_codeclass` VALUES (null, 'PM_CGSQ', '采购申请', null, null, null, '2018-09 ...

  6. CentOS7终端的分辨率和字体修改

    本文转贴自https://blog.csdn.net/u010566813/article/details/40502819 一.修改分辨率 修改/boot/grub2/grub.cfg 添加如上,具 ...

  7. android BLE Peripheral 做外设模拟设备,供ios、android 连接通讯。

    为了能让其它设备可以发现其设备,先启动特定广播.看自己需要什么广播格式. 对于广播可见的mac address: 在调用startAdvertising();时,mac address 就会改变. 并 ...

  8. 几个VB常见又内涵的错误

    第一位内涵的就是:没有对象 找到对象,却发现是别人的对象 不能加载也不能卸载...这到底是什么对象 哈哈哈~

  9. Vue(二十八)el-cascader 动态加载 - 省市区组件

    1.后台接口为点击加载下一级 ,传省市区id <template> <el-cascader v-model="selectedOptions" placehol ...

  10. 非vue-cli的花括号闪现问题

    <div id="app" v-cloak></div>[v-cloak] { display: none;}这种方式可以解决网速较慢,vue.js文件还没 ...