@ResponseStatus是一个处理异常的注解,可以修饰一个类或者一个方法,当修饰一个类的时候,通常修饰的是一个异常类。在自定义异常类上加上这个注解,当抛出自定义异常的时候,使用这个注解声明的value值和reason值将异常信息返回给客户端,提高可读性。
/**
* 自定义异常类
* @version: 1.0
* @date 2019-02-23 11:53
*/
@ResponseStatus(reason = "发生异常了,请联系管理员!")
public class DemoException extends RuntimeException {
}
Controller方法为
@RequestMapping("/testui")
public String gotoTest(HttpServletRequest request) {
try {
int result = 5 / 0;
} catch (Exception e) {
throw new DemoException();
}
return "test/testLayui";
}
@ExceptionHandler作用在方法上,并且运行时有效。源码如下:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
Class extends Throwable>[] value() default {};
}
该注解的方法支持的参数除了HttpServletRequest、HttpServletResponse等对象之外,还支持一个异常参数,包括一般的异常或自定义异常。如果@ExceptionHandler方法是在控制器内部定义的,那么它会接收并处理由控制器中的@RequestMapping方法抛出的异常。如果单独使用@ExceptionHandler,只能在当前Controller中处理异常, 如果将@ExceptionHandler方法定义在@ControllerAdvice类中,那么它会处理相关控制器中抛出的异常。
该注解还可以接受一个异常类型的数组作为参数值。如果抛出已在列表中声明的异常,
那么相应的@ExceptionHandler方法将会被调用。如果没有给注解任何参数值,那么方法参数所声明的异常就是默认处理的异常类型。
Controller代码如下:
@RequestMapping("/testui")
public String gotoTest(HttpServletRequest request) {
int result = 5 / 0;
return "test/testLayui";
}
/**
* 在抛出异常的时候,控制器会使用@ExceptionHandler注解的方法去处理异常
* @param ex
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Map testErrorPage(Exception ex){
Map errorMap = new HashMap<>();
errorMap.put("code","500");
errorMap.put("message","异常!请联系管理员");
errorMap.put("data","请求异常");
return errorMap;
}
@ControllerAdvice注解是Spring3.2开始提供的新注解,是一个控制器增强功能注解。源码如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class>[] basePackageClasses() default {};
Class>[] assignableTypes() default {};
Class extends Annotation>[] annotations() default {};
}
该注解使用@Component注解,可以使用< context:component-scan >扫描该注解,所以需要把使用该注解的类放到扫描路径下才会有效果。扫描到@ControllerAdvice注解之后,会将@ControllerAdvice注解修饰的类内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有@RequestMapping注解的方法。
全局异常处理类如下:
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理Exception异常
* @param ex
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Map testErrorPage(Exception ex){
Map errorMap = new HashMap<>();
errorMap.put("code","5000");
errorMap.put("message",ex.getMessage());
errorMap.put("data","请求异常");
return errorMap;
}
/**
* 处理自定义异常
* @param ex
* @return
*/
@ExceptionHandler(value = DemoException.class)
@ResponseBody
public Map testDemoErrorPage(DemoException ex){
Map demoMap = new HashMap<>();
demoMap.put("code","500");
demoMap.put("message",ex.getMessage());
demoMap.put("data","请求异常");
return demoMap;
}
控制器代码如下:
@RequestMapping("/testui")
public String gotoTest(HttpServletRequest request) {
int result = 5 / 0;
return "test/testLayui";
}
@RestControllerAdvice注解是@ControllerAdvice和@ResponseBody组合之后的注解。使用了@RestControllerAdvice相当于使用了@ControllerAdvice注解并且该类中所有使用@ExceptionHandler注解的方法都默认使用@ResponseBody注解。
该注解源码如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class>[] basePackageClasses() default {};
Class>[] assignableTypes() default {};
Class extends Annotation>[] annotations() default {};
}