SpringMVC全局异常处理

 

SpringMVC执行流程:
发起请求--->前端控制器--->调用处理器映射器获取具体的处理器---->
返回前端控制器--->处理器适配器--->
调用具体的处理器--->返回数据给前端控制器--->
视图解析器--->返回视图--->前端控制器处理视图返回给用户
@ResponseBody
响应正文,将方法的返回值作为正文返回,但是Java对象不能被网页所识别,为了识别这个数据,mvc提供了
httpmessageconvert来将Java对象转成http的正文数据,如果数据对象本身就是String类型,会原样输出,
如果是Java的其他对象,会进行转换,默认是通过jackson转成json数据但是可以更改。
@Controller
public class UserController {
    @RequestMapping(value = "/test1")
    @ResponseBody
    public String test1(){
        System.out.println("UserController.test");
        int i = 10/0;//这里有一个异常,如果不处理会把异常信息直接暴露给用户
        return "ok";
    }
    @RequestMapping(value = "/test2")
    @ResponseBody
    //这里处理了异常,但是不能每个方法都进行这样的处理,那样trycatch代码太多了
    public String test2(){
        System.out.println("UserController.test");
        try {
            int i = 10 / 0;
        }catch (ArithmeticException e){
            System.err.println("这里出现异常了");
            e.printStackTrace();
            return "系统正在维护,请联系管理员。。。";
        }
        return "ok";
    }

 

这个是全局处理异常的一种方式,实现HandlerExceptionResolver接口 (这里还需要创建一个error.jsp用来给用户显示):

package com.qf.exception;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * @Author kk
 * @Date 2020/5/14 16:08
 */
@Component//这个类虽然创建了,但是还需要被Spring容器识别,因此加上该注解
public class ExceptionHandler implements HandlerExceptionResolver {
    /**
     * 全局异常处理的方法,项目里的异常都可以在这里处理
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o 某个bean出现的异常
     * @param e 异常对象
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        System.out.println("ExceptionHandler.resolveException");

        ModelAndView modelAndView = new ModelAndView();

        //设置出现异常后调整的页面
        modelAndView.setViewName("error");
        modelAndView.addObject("errorMsg","系统正在维护,请联系管理员...");

        return modelAndView;
    }
}

这里是处理全局异常的另一种方式(常用),使用注解,写一个类:

package com.qf.exception;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

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

/**
 * @Author kk
 * @Date 2020/5/14 16:20
 */
@Component
@ControllerAdvice //全局异常处理的注解
public class ExceptionHandlerAnnotation {

    //出现ArithmeticException异常,或者该异常的子类都会调用本方法
    @ExceptionHandler(value = ArithmeticException.class)//只有出现这个异常,才会进入本方法
    @ResponseBody
    public Map<String,Object> exception( Exception e){
        System.out.println("ExceptionHandlerAnnotation.exception" + e);
        Map<String,Object> map = new HashMap<>();
        map.put("status","error");
        map.put("msg","系统出现了数学计算异常");
        return map;
    }

    @ExceptionHandler(value = NullPointerException.class)//只有出现这个异常,才会进入本方法
    @ResponseBody
    public Map<String,Object> exception2( Exception e){
        System.out.println("ExceptionHandlerAnnotation.exception" + e);
        Map<String,Object> map = new HashMap<>();
        map.put("status","error");
        map.put("msg","系统出现了空指针异常");
        return map;
    }
}

总结:

1. 如果系统出现异常后SpringMVC默认的处理方式是把异常直接暴露给用户

2.可以在代码里写trycatch语句块进行捕获,但是最后try catch过多难以维护

3.全局异常的处理
    a.使用注解实现
        1)定义一个全局的异常处理Handler
        2)类上面添加@ControllerAdvice
        3)方法上面添加@ExceptionHandler(value = 异常的种类.class)
            当出现当前异常或者当前异常的子类时,就会调用该方法

    b.实现HandlerExceptionResolver接口
        1)复写该接口中的方法,在这个方法里面还需要设置异常出现后的视图.jsp
        2)缺点:只能返回错误视图,如果返回JSON数据比较复杂
        3)这个类需要用@Component来修饰

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值