文章目录
功能需求及处理策略
- 统一处理表现层的异常
- 因为,数据层、业务层均会将异常往上抛,最终都会抛给表现层
- 采取的策略是:面向切面编程,使用Spring的注解,统一管理bean中的异常,
- 无需在每个Controller中定义处理
2. SpringBoot快速处理错误页面

-
在SpringBoot中,只需将错误页面放在指定路径下,特定命名的文件夹下,出现异常会自动访问这些页面
- 指定路径:classPath根目录下的templates路径下
- 指定文件名:error
-
原理应是框架内部设置了默认的处理路径
-
测试:
-
404错误
-
500错误
/** 会话列表显示 */ @RequestMapping(path = "/letter/list", method = RequestMethod.GET) public String getLetterList(Model model, Page page) { Integer.valueOf("abf"); ...
-
3. Spring使用注解统一处理异常
- 对于404错误,直接返回一个提示页面是可以的
- 但对于500错误,除了要返回错误页面,还要对错误信息进行日记记录处理等
- 因此,需要用到Spring的注解统一处理异常
@ControllerAdvice
-
用于修饰类,表示该类是Controller的全局配置类。
- 可以指定扫描的组件,一般就是Controller组件
-
在此类中,可以对Controller进行如下三种全局配置:
- 异常处理方案:@ExceptionHandler
- 绑定数据方案:@ModelAttribute
- 绑定参数方案:@DataBinder
package com.nowcoder.community.controller.advice; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ControllerAdvice; @ControllerAdvice(annotations = Controller.class) public class ExceptionAdvice { }
@ExceptionHandler
- 用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
request.getHeader(“x-requested-with”)
- 可以获取请求的方式
- 是普通的网页请求:HttpRequest
- 还是异步请求:XMLHttpRequest
XMLHttpRequest
-
设置返回的类型:
-
普通的字符串格式:"application/plain
-
向浏览器返回一个字符串,需手动转换为js对象
// 将返回的字符串转为json对象,方便调用 data = $.parseJSON(data);
-
-
Json格式 :"application/json
- 向浏览器返回一个字符串,浏览器会自动转换为Js对象
response.setContentType("application/plain;charset=utf-8");
-
@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);
@ExceptionHandler({Exception.class})
public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException, IOException {
logger.error("服务器发生异常: " + e.getMessage());
// 遍历栈的信息
for(StackTraceElement element : e.getStackTrace()) {
logger.error(element.toString());
}
// 重定向错误页面,但有可能是异步请求,否则返回到json
String xRequestedWith = request.getHeader("x-requested-with");
if(xRequestedWith.equals("XMLHttpRequest")) {
response.setContentType("application/plain;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));
} else {
response.sendRedirect(request.getContextPath() + "/error");
}
}
}
@ModelAttribute
- 用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定数据参数。
- 可以往model中绑定统一的参数数据,给所有controller用
@DataBinder
- 用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器
- 页面传参,会自动转换为请求方法中接收的参数,框架中有定义好的转换器
- 如果页面传入了特殊的参数,框架中定义好的转换器不可用,可以自定义转换器注册上
测试
-
普通请求错误
/** 会话列表显示 */ @RequestMapping(path = "/letter/list", method = RequestMethod.GET) public String getLetterList(Model model, Page page) { // 添加一个错误,进行测试 Integer.valueOf("abf"); ...
-
异步请求错误
/** * 处理ajax异步发布帖子请求 * @param title 帖子主题 * @param content 帖子内容 * @return JSON字符串 */ @RequestMapping(value = "/add", method = RequestMethod.POST) @ResponseBody public String addPost(String title, String content) { // 添加一个错误,进行测试 Integer.valueOf("add"); ...