SpringMVC 注解(五) @ControllerAdvice,@ExceptionHandler
1. ExectionHandler
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* Exceptions handled by the annotated method. If empty, will default to any
* exceptions listed in the method argument list.
*/
Class<? extends Throwable>[] value() default {};
}
说明:
注解的范围:只能注解在方法上
保存时间: 保留到程序运行时,因此在程序运行时,可以通过反射获取带有特定注解的方法
如果使用javadoc 等文档工具,注解的方法会添加到生成的文档中
作用:
定义一个类的异常处理
当在一个方法上注解@ExceptionHandler(异常.class) 时,类中所有方法出现括号中的异常时会自动执行被注解的方法,提供友好视图, 一个类中可以在多个方法上加上@ExceptionHandler,一个ExceptionHandler 注解可以设置多个异常的处理到一个方法,但是只对本类中出现的异常进行捕获
例子:
如图所示,这个正常的controller,当在浏览器中输入 项目名/test/test 会进入test方法,但是test会执行获得type参数的操作,当没传值时就出现NullPointExceptino ,此时方法会自动跳转执行error ,向前台返回设置的内容或视图
package com.controller;
import com.util.TestServiceFactory;
import com.util.TypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.service.TestService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping(value = "test")
public class TestController {
@Autowired
TestServiceFactory testServiceFactory;
private TestService testService;
@ResponseBody
@RequestMapping("test")
public String test(HttpServletRequest request, HttpServletResponse response){
String type = request.getParameter("type");
testService = getTestService(type);
return testService.test();
}
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String error() {
return "请输入必须参数";
}
}
2 . @ControllerAdvice
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
说明:
定义在类或枚举或接口上
保留时间: 在程序运行时仍然保留
会显示在文档中
@Component 表明spring会把这个注解标记的类,自动注入servlet上下文
作用:
定义全局的异常处理
如果一个异常,不仅仅可能会在一个类出现,而是会在多个类中出现,比如NullPointException, 这个时候如果我们要捕获异常,就要在每个类中定义一个被@ExceptionHandler 注解的方法处理,重复且麻烦,用@ControllerAdvice 和 @ExceptionHandler 组合就捕获全局异常
例子:
说明:这样在注解了@ControllerAdvice 的类上就可以定义全局异常,不用在每个类中分别定义
注意: 如果某个Controller类中已经定义了某个异常的处理,而注解了@ControllerAdvice的类中也定义这个异常的处理方法,会优先使用Controller类中的定义处理方法
package com.controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String errro() {
return "失败,请重试";
}
}
结合@ResponseStatus 使用,返回错误视图和httpcode
@ControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(code = HttpStatus.BAD_REQUEST,reason = "失败请重试")
public void errro() {
}
}