天天看点

springboot 不继承RuntimeException 实现全局统一处理异常的方法

       将项目接口写完之后,因为项目中部分使用了 Assert.notNull这个API,需要处理一下异常,想到了以前都是使用继承RuntimeException 的方法来实现的,需要创建多个文件,本人比较懒就去查了查有没有不继承RuntimeException就能实现的方法,在网上查到了一些资料,下面先上代码:

package com.example.demo.config;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
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
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        log.error("全局异常被调用");
        HandlerMethod handlerMethod = (HandlerMethod) o;//发生异常的方法
        handlerMethod.toString();
        log.error("handlerMethod  toString:"+handlerMethod);
        e.getMessage(); // e 是异常
        e.printStackTrace();
        log.info("异常信息:"+e.getMessage());
        ModelAndView modelAndView = new ModelAndView();
        //统一处理异常返回结果 
        Map<String,String>  exception = new HashMap<>();
        exception.put("code","500");
        exception.put("msg","服务器内部发生异常");
        exception.put("analysis",e.getMessage());
        //最好使用string类型的参数,使用Map和list类型的参数接收参数的时候会报错
        modelAndView.addObject("exception", JSONObject.toJSONString(exception));
//        try {
//            httpServletResponse.setContentType("text/html;charset=utf-8");
//            PrintWriter writer = httpServletResponse.getWriter();
//            writer.print(JSONObject.toJSONString(exception));
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }
        //携带处理好的异常结果集重定向
        modelAndView.setViewName("redirect:/hello/callBack");
        return modelAndView;
    }
}
           
package com.example.demo.controller;

import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Map;

@RestController

public class HelloContrller {

    @RequestMapping("/hello/exception")
    public Object hello(){
        Assert.notNull(null,"测试异常");
        return "hello";
    }
    @RequestMapping("/hello/callBack")
    public Object hello(HttpServletRequest request, String exception){
//        Assert.notNull(null,"测试异常");
        Map<String, String[]> parameterMap = request.getParameterMap();
//        String a = request.getParameter("exception");
        return exception;
    }
    @RequestMapping("/")
    public ModelAndView hello(ModelAndView modelAndView) {
        modelAndView.setViewName("html/jsTest.html");
        return modelAndView;
    }
}
           

浏览器访问:http://{ip:port}/hello/exception 测试

实现该接口,注册到spring容器中,当产生异常的时候会调用该接口来处理,注意,当返回值指定视图时会自动跳转至指定的视图中去,如果返回null,会继续调用下一个异常处理器去执行。(注:1、如果抛的异常已经被捕捉到,那么这个配置是不会处理的,2、参考文档中提到Controller抛的会处理,我测试了一下如果异常不处理service中的异常也会处理,其他的异常没有测试,具体原理请去了解spring 异常处理的资料 我对这方面也不是很了解,就不献丑了,下面贴出参考文档的出处)

参考文档:https://blog.csdn.net/u013194072/article/details/79044286