@ControllerAdvice注解标注的类,内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法可以应用到所有的 @RequestMapping注解的方法上。不过看了下,大家都说只有当使用@ExceptionHandler用处最大。下面主要演示@ControllerAdvice注解标识的类中来定义错误的页面,下面介绍两种页面显示错误页面的方法
一、把错误信息通过@ResponseBody返回到请求页面中的<body>
标签中
1、首先创建一个@Controller层,在其中定义响应请求的方法,处理请求的方法故意抛出一个异常,以便在后面定义处理异常的类。
package com.lzj.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
/*该方法用于响应http://localhost:8080/errorPage请求*/
@RequestMapping("/errorPage")
/*注意此地的errorMethod方法千万不要定义成error,因为Spring boot框架中默认有error方法,如果此地写成error方法,与Spring boot的内部的方法冲突*/
/*这个“error”模型属性是在后面@ModelAttribute注解标注的addAttributes方法中放进去的*/
public String errorMethod(@ModelAttribute("error") String error) throws Exception{
System.out.println("-----error-------" + error);
throw new MyException("500", "服务器响应出错");
}
}
其中MyException类为:
package com.lzj.springboot.controller;
public class MyException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String code;
private String msg;
public MyException(String code, String msg){
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
2、定义处理异常类,当Controller层中的处理请求的方法抛出异常时,由处理异常的类来处理异常。处理异常的类要用@ControllerAdvice注解标识,在该标识的类内部定义的方法上用@ExceptionHandler、@InitBinder、@ModelAttribute注解标识,这些方法才会作用Controller层的@RequestMapping注解的方法上。
package com.lzj.springboot.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class MyControllerAdvice {
/*@ModelAttribute标注的方法在@RequestMapping标注的方法之前执行,因此在@RequestMapping标注的方法和在@ExceptionHandler标注的方法中都可以获取在@ModelAttribute标注的方法中设置的模型参数*/
@ModelAttribute
public void addAttributes(Model model){
model.addAttribute("error", "This is Error information");
model.addAttribute("exception", "This is Exception information");
}
/*下面返回到body体中,以json的形式显示*/
/*@ExceptionHandler(value=MyException.class)表示有MyException类型的异常时,触发excepthionHandler方法;
@ResponseBody主机表示把map的信息通过json的形式返回请求页面*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@ResponseBody
@ExceptionHandler(value=MyException.class)
public Map excepthionHandler(MyException exception){
System.out.println("-------------excepthionHandler----------------");
Map map = new HashMap();
map.put("code", exception.getCode());
map.put("msg", exception.getMsg());
return map;
}
// /*下面返回到body体中,以字符串的形式显示*/
// @SuppressWarnings({ "rawtypes", "unchecked" })
// @ResponseBody
// @ExceptionHandler(value=MyException.class)
// public String excepthionHandler(MyException exception){
// System.out.println("-------------excepthionHandler----------------");
// Map map = new HashMap();
// map.put("code", exception.getCode());
// map.put("msg", exception.getMsg());
// return "excepthionHandler";
// }
}
3、启动类为:
@SpringBootApplication(scanBasePackages="com.lzj.springboot")
public class App {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(App.class);
app.run(args);
}
}
启动启动类,在浏览器中发送http://localhost:8080/errorPage请求后,又Controller层中的errorMethod方法响应请求,在errorMethod()方法响应前,先执行MyControllerAdvice中@ModelAttribute标注的addAttributes()方法。然后执行 errorMethod()方法,errorMethod()方法执行后抛出MyException异常,由MyControllerAdvice类中的@ExceptionHandler标识的excepthionHandler()方法获取抛出的MyException类型的异常,并处理异常,把错误信息返回到请求页面的body中,因为在excepthionHandler()方法上面有@ResponseBody注解。
eclipse中Console中输出:-----error-------This is Error information
二、渲染自定义的页面返回给浏览器
Controller类和启动类与上面的示例相同,下面只需要修改@ControllerAdvice注解标识的MyControllerAdvice如下:
@ControllerAdvice
public class MyControllerAdvice {
@ExceptionHandler(value=MyException.class)
public ModelAndView exceptionMethod(MyException myException){
ModelAndView modelAndView = new ModelAndView();
/*定义视图的名字*/
modelAndView.setViewName("error");
modelAndView.addObject("code", myException.getCode());
modelAndView.addObject("msg", myException.getMsg());
System.out.println("code=" + myException.getCode() + ";msg=" + myException.getMsg());
/*返回视图,视图为error.ftl*/
return modelAndView;
}
@ModelAttribute
public void addAttributes(Model model){
model.addAttribute("error", "This is Error information");
model.addAttribute("exception", "This is Exception information");
}
}
在/templates/目录下创建error.ftl模板视图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${error}</title>
</head>
<body>
<h1>${code}</h1>
<h1>${msg}</h1>
</body>
</html>
运行spring boot工程,在浏览器中发送http://localhost:8080/errorPage请求,然后执行addAttributes()方法,设置模型参数,然后由errorMethod()执行请求,抛出异常,最后由exceptionMethod()捕获异常,处理异常,并返回error.ftl视图给浏览器显示。