原文:https://blog.csdn.net/tianyaleixiaowu/article/details/70145251

全局异常处理是个比较重要的功能,一般在项目里都会用到。
我大概把一次请求分成三个阶段,来分别进行全局的异常处理。
一:在进入Controller之前,譬如请求一个不存在的地址,404错误。
二:在执行@RequestMapping时,进入逻辑处理阶段前。譬如传的参数类型错误。
三:以上都正常时,在controller里执行逻辑代码时出的异常。譬如NullPointerException。
第一种情况:

import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Created by wuwf on 17/4/12.
*/
@RestController
public class FinalExceptionHandler implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
} @RequestMapping(value = "/error")
public Object error(HttpServletResponse resp, HttpServletRequest req) {
// 错误处理逻辑
return "其他异常";
}
}

第二种情况:
使用@ControllerAdvice

/**
* Created by wuwf on 17/3/31.
* 全局异常处理
*/
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
private static Logger logger = LogManager.getLogger(GlobalExceptionHandler.class.getName());
// @ExceptionHandler(value = Exception.class)
// public ModelAndView defaultHandler(HttpServletRequest request, Exception e) throws Exception {
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.addObject("exception", e);
// modelAndView.addObject("url", request.getRequestURL());
// modelAndView.setViewName("error");
// return modelAndView;
// } /**
* 在controller里面内容执行之前,校验一些参数不匹配啊,Get post方法不对啊之类的
*/
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
System.out.println("错误"); return new ResponseEntity<Object>("出错了", NOT_EXTENDED); }
}

定义一个类,使用@ControllerAdvice注解,继承ResponseEntityExceptionHandler类,这个类里面实现了很多方法,可以去看看,包括一些参数转换,请求方法不支持等等之类的异常都会被捕获。
被捕获的原因是@ExceptionHandler标签,里面所有的异常类只要发生了,就会被这个方法所捕获。

第三种情况:
当第一、第二种都没出异常,进入到实际逻辑执行了,然后发生了异常,这样就可以自己定义一个ExceptionHandler的方法,来处理相应的Exception。

/**
* Created by wuwf on 17/3/31.
* 全局异常处理
*/
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
private static Logger logger = LogManager.getLogger(GlobalExceptionHandler.class.getName());
// @ExceptionHandler(value = Exception.class)
// public ModelAndView defaultHandler(HttpServletRequest request, Exception e) throws Exception {
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.addObject("exception", e);
// modelAndView.addObject("url", request.getRequestURL());
// modelAndView.setViewName("error");
// return modelAndView;
// } /**
* 在controller里面内容执行之前,校验一些参数不匹配啊,Get post方法不对啊之类的
*/
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
System.out.println("错误"); return new ResponseEntity<Object>("出错了", NOT_EXTENDED); } @ExceptionHandler(value = Exception.class)
@ResponseBody
public ErrorInfo<String> jsonHandler(HttpServletRequest request, Exception e) throws Exception {
ErrorInfo<String> r = new ErrorInfo<>();
r.setMessage(e.getMessage());
r.setCode(ErrorInfo.ERROR);
r.setData("发生异常");
r.setUrl(request.getRequestURL().toString()); log(e, request); return r;
} private void log(Exception ex, HttpServletRequest request) {
logger.error("************************异常开始*******************************");
// if(getUser() != null)
// logger.error("当前用户id是" + getUser().getUserId());
logger.error(ex);
logger.error("请求地址:" + request.getRequestURL());
Enumeration enumeration = request.getParameterNames();
logger.error("请求参数");
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement().toString();
logger.error(name + "---" + request.getParameter(name));
} StackTraceElement[] error = ex.getStackTrace();
for (StackTraceElement stackTraceElement : error) {
logger.error(stackTraceElement.toString());
}
logger.error("************************异常结束*******************************");
}
}

上面都是restful的情况,返回个json。对于要返回view的按下面的处理。

@Component
public class ExceptionHandler implements HandlerExceptionResolver {
private static Logger log = LoggerFactory.getLogger(ExceptionHandler.class); @Override
public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
// 异常处理逻辑 goes here
log.info("got exception: {}", ex.getClass());
return new ModelAndView("pc/500");
}
}

从SpringMVC源码中可知,DispatcherServlet中如果产生了异常,则接下来会在processDispatchResult()方法中查询当前容器中是否有HandlerExceptionResolver接口的实现类,如果有则调用它的resolveException()方法,得到返回的View,如果没有则使用框架默认的异常处理类。

导入包

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-redis')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-freemarker')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-web-services')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
compile('org.springframework.boot:spring-boot-starter-log4j2:2.0.3.RELEASE')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
compileOnly('org.projectlombok:lombok')
runtime('mysql:mysql-connector-java')
compile ('com.alibaba:fastjson:1.2.47')
testCompile('org.springframework.boot:spring-boot-starter-test')
compile ('org.apache.shiro:shiro-spring:1.3.2')
compile('com.github.pagehelper:pagehelper-spring-boot-starter:1.2.3')
compile ('com.google.guava:guava:18.0')
compile 'org.apache.commons:commons-lang3:3.7'
compile 'org.apache.shiro:shiro-core:1.4.0'
compile 'org.springframework:spring-context:5.0.7.RELEASE'
compile 'javax.servlet:javax.servlet-api:3.1.0'

最新文章

  1. 剑指offer-二叉树的深度
  2. CodeSnippet.info 开源说明 和 环境搭建 (第一版)
  3. mysql workbench EER model 乱码
  4. CSU 1120 病毒(DP)
  5. 模仿MFC封装Windows API
  6. HDU 1024 (不重叠m段最大和) Max Sum Plus Plus
  7. 深入理解计算机系统第二版习题解答CSAPP 2.15
  8. MongoDB log4j 日志整合
  9. Android 利用摄像头指尖测试心率
  10. fedora 18 源码编译 android 4.0.1
  11. MySQL-Front 出现“程序注册时间到期 程序将被限制模式下运行”解决方式
  12. Linux多线程实践(6) --Posix读写锁解决读者写者问题
  13. L3-015 球队“食物链” (30 分)
  14. Golang:接口(interface)
  15. [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ...
  16. redis----------windows下安装redis以及PHP的redis扩展
  17. jQuery首页更换背景皮肤
  18. MissingNumber缺失的数字,FirstMissingPositive第一个缺失的正数
  19. 让IE兼容console——“由于出现错误80020101而导致此项操作无法完成”的解决方案
  20. Latex技巧:在图表序号中加入章节号(实现诸如&ldquo;图1.1.2&rdquo;这样的图表序号)

热门文章

  1. mysql查询两张表更改一张表数据
  2. [MySQL] mysql地理位置服务geometry字段类型
  3. 网络流(2)——用Ford-Fullkerson算法寻找最大流
  4. 【cf600】E. Lomsat gelral(dsu on tree)
  5. 1. Vue - ES6
  6. 网络服务—VSFTP
  7. 炫酷的CSS3响应式表单
  8. ResultMap(还没细看)
  9. vue 多种方式控制style属性
  10. Note | PyTorch