SpringBoot 自定义异常拦截

连接数据库完成以后本想要研究一下整合 shiro 和 vue 但是突然发现 404 等错误页面还是原来 SpringBoot 自带的,所以先来整理一下 SpringBoot 的异常处理

 

首先根据原来 SpringMVC 的处理方法,我新建了一个 GlobalExceptionHandler 文件:

package com.seventeen.core.exception;

import com.alibaba.fastjson.JSON;
import com.seventeen.core.ResultObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

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

/**
 * Desc
 *
 * @author : seventeenYear
 * @date : 2020/9/28
 */
@ControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 运行时异常捕获
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ModelAndView error(HttpServletRequest request, RuntimeException e){
        e.printStackTrace();
        return createBody(request, ResultObject.error(e.getMessage()),500);
    }

    /**
     * 404捕获
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public ModelAndView error(HttpServletRequest request, NoHandlerFoundException e){
        e.printStackTrace();
        return createBody(request, ResultObject.error(e.getMessage()),404);
    }

    /**
     * 判断是否ajax
     * @param request
     * @return
     */
    private boolean isAjax(HttpServletRequest request){
        String requestedWith = request.getHeader("x-requested-with");
        if (requestedWith != null && requestedWith.equalsIgnoreCase("XMLHttpRequest")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 生成返回对象
     * @return
     */
    private ModelAndView createBody(HttpServletRequest request, ResultObject ro, int errorCode){
        ModelAndView mv = new ModelAndView();
        System.out.println("运行 createBody 方法");
        if(isAjax(request)){
            MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
            jsonView.setAttributesMap(JSON.parseObject(JSON.toJSONString(ro), Map.class));
            mv.setView(jsonView);
            mv.setStatus(HttpStatus.valueOf(errorCode));
            return mv;
        }else{
            String uri = request.getRequestURI();
            //获取错误页面,跳转并加入返回状态
            String errorUrl = getErrorUrl(uri);
            mv.setViewName("forward:" + errorUrl + "?code=" + errorCode + "&msg=" + ro.getMessage());
            mv.setStatus(HttpStatus.valueOf(errorCode));
            return mv;
        }
    }

    /**
     * 根据登陆用户,获取对应的错误页面
     * @return
     */
    private String getErrorUrl(String uri){
        String[] uriArr = StringUtils.split(uri,"/");
        String errorUrl = "";
        System.out.println("getErrorUrl");
        errorUrl = "/admin/base/adminbase/index";
        return errorUrl;
    }

}
GlobalExceptionHandler

因为这里还没有编写相关的错误页面,所以暂时先用   /admin/base/adminbase/index  数据查询页面代替。

 

 

 这是  /admin/base/adminbase/index  数据查询页面,如果我们之后的异常返回页面上面一样,就说明我们成功了!!!

我们编写一个错误页面:

http://127.0.0.1:8080/admin/base/adminbase/errortest:

    @ResponseBody
    @RequestMapping(value = "errortest")
    public ModelAndView errorTest(){
        int zero = 0;
        int result = 100/zero;
        return resultMvJson(ResultObject.success("", adminBaseService.getIndexInfo()));
    }
AdminBaseController

一个简单的  /by zero 错误,我们进行一下测试:

 

 

 就在我以为我要成功了的时候,我测试了一下404异常,发现还是原来的样子没有变。

之后我经过在网上一顿搜索,我终于发现了原因:

使用  @ControllerAdvice + @ExceptionHandler 注解是可以处理别的异常,但是无法处理404异常,即使在配置文件中加上配置也有问题(不能返回静态资源)。经过调试,找到了完美的解决方法!!!

新建一个404异常处理文件:

package com.seventeen.core.exception;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
public class NotFoundException implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping(value = {"/error"})
    @ResponseBody
    public Object error(HttpServletRequest request) {
        Map<String, Object> body = new HashMap<>();
        body.put("error", "not found");
        body.put("code", "404");
        return body;
    }
}
NotFoundException

 

编写结束之后,测试一下:

SpringBoot 异常处理成功!!!

 

posted @ 2021-02-25 13:58  拾柒年  阅读(365)  评论(0)    收藏  举报