博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring3.2新注解@ControllerAdvice
阅读量:5834 次
发布时间:2019-06-18

本文共 6507 字,大约阅读时间需要 21 分钟。

@ControllerAdvice,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强。让我们先看看@ControllerAdvice的实现:

@Target(ElementType.TYPE)  @Retention(RetentionPolicy.RUNTIME)  @Documented  @Component  public @interface ControllerAdvice {    }

使用 @ControllerAdvice,不用任何的配置,只要把这个类放在项目中,Spring能扫描到的地方。就可以实现全局异常的回调。

 没什么特别之处,该注解使用@Component注解,这样的话当我们使用<context:component-scan>扫描时也能扫描到。

其javadoc定义是:

写道
/*** Indicates the annotated class assists a "Controller".** 

Serves as a specialization of {

@link Component @Component}, allowing for* implementation classes to be autodetected through classpath scanning.**

It is typically used to define {

@link ExceptionHandler @ExceptionHandler},* {
@link InitBinder @InitBinder}, and {
@link ModelAttribute @ModelAttribute}* methods that apply to all {
@link RequestMapping @RequestMapping} methods.** @author Rossen Stoyanchev* @since 3.2*/

  • @ControllerAdvice是一个@Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。

  • Spring4之前,@ControllerAdvice在同一调度的Servlet中协助所有控制器。Spring4已经改变:@ControllerAdvice支持配置控制器的子集,而默认的行为仍然可以利用。

  • 在Spring4中, @ControllerAdvice通过annotations(), basePackageClasses(), basePackages() 方法定制用于选择控制器子集。

即把@ControllerAdvice注解内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法。非常简单,不过只有当使用@ExceptionHandler最有用,另外两个用处不大。

 先看一个示例:

定义一个业务异常,这个异常交给@ControllerAdvice中的@ExceptionHandler处理。

package com.dxz.web.controller.excepion;/** * 业务异常 */public class BusinessException extends Exception {    private static final long serialVersionUID = 1L;    // 业务类型    private String bizType;    // 业务代码    private int bizCode;    // 错误信息    private String message;    public BusinessException(String bizType, int bizCode, String message) {        super(message);        this.bizType = bizType;        this.bizCode = bizCode;        this.message = message;    }    public BusinessException(String message) {        super(message);        this.bizType = "";        this.bizCode = -1;        this.message = message;    }    public BusinessException(String bizType, String message) {        super(message);        this.bizType = bizType;        this.bizCode = -1;        this.message = message;    }    public BusinessException(int bizCode, String message) {        super(message);        this.bizType = "";        this.bizCode = bizCode;        this.message = message;    }    public String getBizType() {        return bizType;    }    public void setBizType(String bizType) {        this.bizType = bizType;    }    public int getBizCode() {        return bizCode;    }    public void setBizCode(int bizCode) {        this.bizCode = bizCode;    }    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }}

用@ControllerAdvice为@RequestMapping注解的方法的提供@ExceptionHandler、@InitBinder、@ModelAttribute的功能。

package com.dxz.web.controller.excepion;import java.beans.PropertyEditor;import java.sql.SQLException;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.propertyeditors.CustomDateEditor;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;import com.dxz.web.model.User;/** * @ModelAttribute用于属性注入 * @InitBinder用于参数的统一处理 * @ExceptionHandler用于捕获异常统一处理 */@ControllerAdvicepublic class GlobalExceptionHandler {    private final static String EXPTION_MSG_KEY = "message";    @ModelAttribute      public User newUser() {          System.out.println("============应用到所有@RequestMapping注解方法,在其执行之前把返回值放入Model");          return new User();      }         @InitBinder    public void dataBinder(WebDataBinder binder) {        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");        PropertyEditor propertyEditor = new CustomDateEditor(dateFormat, true); // 第二个参数表示是否允许为空        binder.registerCustomEditor(Date.class, propertyEditor);    }    @ExceptionHandler(BusinessException.class)    @ResponseBody    public void handleBizExp(HttpServletRequest request, Exception ex) {        System.out.println("Business exception handler  " + ex.getMessage());        request.getSession(true).setAttribute(EXPTION_MSG_KEY, ex.getMessage());    }    @ExceptionHandler(SQLException.class)    public ModelAndView handSql(Exception ex) {        System.out.println("SQL Exception " + ex.getMessage());        ModelAndView mv = new ModelAndView();        mv.addObject("message", ex.getMessage());        mv.setViewName("sql_error");        return mv;    }}

测试的controller:

package com.dxz.web.controller;import java.io.IOException;import java.io.Writer;import java.sql.SQLException;import java.util.Date;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import com.dxz.web.controller.excepion.BusinessException;@Controller@RequestMapping("/user")public class UserController {    @RequestMapping("login")    public String login() {        return "login";    }    @RequestMapping("login2")    public String login2() throws Exception {        throw new SQLException("数据库出错");    }    @RequestMapping("login3")    public String login3() throws Exception {        throw new BusinessException("业务执行异常");    }    @RequestMapping("dataBinder/{date}")    public void testDate(@PathVariable Date date, Writer writer) throws IOException {        System.out.println("date:" + date);        writer.write(String.valueOf(date.getTime()));    }    // 此方法抛出的异常不是由GlobalExceptionHandler处理    // 而是在catch块处理    @RequestMapping("login4")    public String login4() {        try {            throw new BusinessException("业务执行异常");        } catch (BusinessException e) {            System.out.println("自己消化异常");        }        return "login";    }}

@ExceptionHandler演示,分别访问:

测试结果:

 @InitBinder演示,分别访问:

 

1、@ModelAttribute注解的方法作用请参考

2、@InitBinder注解的方法作用请参考

3、@ExceptionHandler,异常处理器,此注解的作用是当出现其定义的异常时进行处理的方法,其可以使用springmvc提供的数据绑定,比如注入HttpServletRequest等,还可以接受一个当前抛出的Throwable对象。可以参考javadoc或snowolf的。

 

该注解非常简单,大多数时候其实只@ExceptionHandler比较有用,其他两个用到的场景非常少,这样可以把异常处理器应用到所有控制器,而不是@Controller注解的单个控制器。

转载地址:http://rzucx.baihongyu.com/

你可能感兴趣的文章
第四章 mybatis批量insert
查看>>
Java并发框架——什么是AQS框架
查看>>
【数据库】
查看>>
WindowManager.LayoutParams 详解
查看>>
find的命令的使用和文件名的后缀
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
asp.net怎样在URL中使用中文、空格、特殊字符
查看>>
实现跨交换机VLAN间的通信
查看>>
python例子
查看>>
环境变量(总结)
查看>>
ios之UILabel
查看>>
Java基础之String,StringBuilder,StringBuffer
查看>>
1月9日学习内容整理:爬虫基本原理
查看>>
安卓中数据库的搭建与使用
查看>>
AT3908 Two Integers
查看>>
C++ 0X 新特性实例(比较常用的) (转)
查看>>
node生成自定义命令(yargs/commander)
查看>>
.NET 设计规范--.NET约定、惯用法与模式-2.框架设计基础
查看>>
win7 64位+Oracle 11g 64位下使用 PL/SQL Developer 的解决办法
查看>>