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; } }
因为这里还没有编写相关的错误页面,所以暂时先用 /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())); }
一个简单的 /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; } }
编写结束之后,测试一下:

SpringBoot 异常处理成功!!!

浙公网安备 33010602011771号