springmvc、 springboot 项目全局异常处理

异常在项目中那是不可避免的,通常情况下,我们需要对全局异常进行处理,下面介绍两种比较常用的情况。

准备工作:

在捕获到异常的时候,我们通常需要返回给前端错误码,错误信息等,所以我们需要手动封装一个jsonData对象,这里为了方便,我直接通过返回布尔类型来进行判断成功或失败,在实际的项目中更多是返回状态码 比如 0、1 、404 、500 等,在这里不影响我们演示。

jsondata对象

springmvc、 springboot 项目全局异常处理_第1张图片

自定义一个异常  (注意需要继承RuntimeException,因为在spring中仅有RuntimeException支持事务)

springmvc、 springboot 项目全局异常处理_第2张图片

 

情况一、对全局进行捕获,并统一返回json数据

我们通过@ControllerAdvice的方式来捕获全局异常

主要代码如下:

import com.me.exception.RbacException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class ExceptionHandReturnJson {

    private final String UNKNOW_EX_MSG = "未知错误";

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public JsonData handle(Exception e){
        JsonData result = new JsonData();
        /*判断异常的类型*/

        // 如果是自定义异常
        if(e instanceof RbacException){
            log.error("【自定义异常】:{}"+e.getMessage());
            result = JsonData.fail(e.getMessage());
        }else{
            log.error("【系统异常】:{}"+e.getMessage());
             result = JsonData.fail(UNKNOW_EX_MSG);
        }
        return result;
    }
}

  然后确保我们这个类所在的包被扫描到即可。

  下面我们自定义一个类,并手动产生一个异常:

springmvc、 springboot 项目全局异常处理_第3张图片

springmvc、 springboot 项目全局异常处理_第4张图片

运行结果:

springmvc、 springboot 项目全局异常处理_第5张图片

springmvc、 springboot 项目全局异常处理_第6张图片

 

情况二、对全局异常进行捕获,返回modelandview类型

我们通过实现HandlerExceptionResolver 的方式来捕获全局异常

主要代码如下:

package com.me.common;

import com.me.exception.RbacException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理
 */

@Slf4j
public class ExceptionHand implements HandlerExceptionResolver {


    private final String UNKNOW_EX_MSG = "未知错误";

    /**
     * 通过实现HandlerExceptionResolver 接口,对捕获到的异常进行处理
     * 当然,我们需要在spring容器中创建这个bean
     * @param request
     * @param response
     * @param o
     * @param e
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object o, Exception e) {
        // 请求地址
//        String url = request.getRequestURL().toString();

        ModelAndView mav = new ModelAndView();
        // 如果是自定义异常
        if(e instanceof RbacException){
            log.error("【自定义异常】:{}"+e.getMessage());
            JsonData result = JsonData.fail(e.getMessage());
            mav.addObject("result",result);
        }else{
            log.error("【系统异常】:{}"+e.getMessage());
            JsonData result = JsonData.fail(UNKNOW_EX_MSG);
            mav.addObject("result",result);
        }
        // 设置异常处理返回的页面,在/views/exception.jsp
        mav.setViewName("exception");
        return mav;
    }

}

然后我们需要在spring容器中创建这个类的bean , 按照springmvc和springboot不同的做法都可以。

 

  同样,我们还是用刚才的方法进行测试

springmvc、 springboot 项目全局异常处理_第7张图片

springmvc、 springboot 项目全局异常处理_第8张图片

因为返回的是modelAndView类型的对象,所以我们需要创建一个view

springmvc、 springboot 项目全局异常处理_第9张图片

springmvc、 springboot 项目全局异常处理_第10张图片

运行结果:

springmvc、 springboot 项目全局异常处理_第11张图片

springmvc、 springboot 项目全局异常处理_第12张图片

 

===========================================================================================

总结:

上面就是两种种捕获全局异常进行处理的不同方式,

1.实现HandlerExceptionResolver接口,返回modelAndView类型

2.通过@ControllerAdvice注解捕获,并通过@ResponseBody返回json类型

具体使用哪种看实际的项目,个人更喜欢第一种,统一返回json类型。

其他:

更规范的json返回对象是code码而不是boolean类型的,这里只为了做演示。那么在我们使用code码的时候,我们抛异常的时候可以自定义传入code以及msg ,这时建议用枚举来管理二者关系,抛异常的时候传入枚举类型,捕获的时候再从枚举中取值。

更详细的课程教学,请看廖师兄的课程  https://www.imooc.com/learn/810

 

 

 

你可能感兴趣的:(springboot,springmvc,异常处理,java,springboot,springmvc,异常处理)