全局异常处理用AOP处理,其实全局异常处理主要是让客户看起来好看点,总不能给客户看Tomcat404的页面吧。
用到的注解:
- @ControllerAdvice:包含@Component。可以被扫描到。统一处理异常。
- @ResponseBody:返回JSON格式数据
- @ExceptionHandler:指定捕获的异常类型
案例
/**
* 全局异常处理,主要处理返回json和返回页面的方法的异常。
*/
@ControllerAdvice(basePackages = "com.blacktv.springboot.Controller")//指定对哪个包进行统一异常处理
public class Error {
private final static Logger log = Logger.getLogger(Error.class);
@ResponseBody//以json格式返回处理结果
@ExceptionHandler(RuntimeException.class)//指定拦截的异常类型,这里指定运行时异常
/**
* 捕获指定包里的运行时异常并处理,处理结果以JSON的格式返回
* @return
*/
public Map<String, Object> catchRuntimeException() {
Map<String, Object> map = new HashMap<>();
map.put("error", "捕获到异常");
log.error("捕获到运行时异常");//添加到错误日志中
return map;
}
}
测试一下,故意给这个接口传入0:
package com.blacktv.springboot.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试全局异常处理用例,这里是返回json数据的接口
*/
@RestController
public class ResultJson {
@GetMapping(value = "/json")
public String number(int number) {
System.out.println(100 / number);
return "ok";
}
}
再测试另一组
package com.blacktv.springboot.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 测试全局异常处理用例,这里是返回页面数据的接口,用的是Freemarker视图层
*/
@Controller
public class ResultPage {
@GetMapping(value = "/page")
public String number(int number) {
System.out.println(100 / number);
return "index";//index.ftl的内容不重要,重要的是异常处理
}
}
故意触发了两次异常,会有两个日志: