通过@ControllerAdvice,我们可以对于控制器的全局配置放在同一个位置,注解了@Controller的类的方法可使用@ExceptionHandler、@ModelAttribute、@InitBinder注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效。
- @ExceptionHandler:用于全局处理控制器里的异常。
- @ModelAttribute:@ModelAttribute本来的作用是绑定健值对到Model里,此处是让全局的@RequestMapping都能获得此处设置的健值对。
- @InitBinder:用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中。
演示@ExceptionHandler处理全局异常,更人性化的将异常输出给用户。
实战
1 编写ControllerAdvice
@ControllerAdvice
//声明了一个控制器建言,@ControllerAdvice 组合了@Component注解,所以自动注册未Spring的Bean。
public class ExceptionHandlerAdvice {
//在此处定义全局处理,通过value属性可过滤拦截条件,在此处我们可以看出拦截了所有的Exception。
@ExceptionHandler(value = Exception.class)
public ModelAndView exception(Exception exception, WebRequest request) {
ModelAndView modelAndView = new ModelAndView("error");// error页面
modelAndView.addObject("errorMessage", exception.getMessage());
return modelAndView;
}
@ModelAttribute //将键值对添加到全局,所有注解了@RequestMapping的方法可获得此健值对。
public void addAttributes(Model model) {
model.addAttribute("msg", "额外信息");
}
@InitBinder //定制WebDataBinder
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.setDisallowedFields("id"); //忽略request参数的id
}
}
2 编写控制器
@Controller
public class AdviceController {
@RequestMapping("/advice")
public String getSomething(@ModelAttribute("msg") String msg,DemoObj obj){//1
throw new IllegalArgumentException("非常抱歉,参数有误/"+"来自@ModelAttribute:"+ msg);
}
}
3 编写异常展示页面
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>@ControllerAdvice Demo</title>
</head>
<body>
${errorMessage}
</body>
</html>
四 测试
1 访问http://localhost:8080/highlight_springmvc4/advice?id=1&name=cakin