>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 21571 个阅读者 刷新本主题
 * 贴子主题:  【Spring专题】@ControllerAdvice注解的用法 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2021-10-09 11:53:55     消息  查看  搜索  好友  邮件  复制  引用

本文参考《精通Spring:JavaWeb开发技术详解》,作者:孙卫琴,清华大学出版社出版

当一个Web应用中的多个控制器类要完成一些共同的操作,传统的做法是定义一个控制器父类(例如BaseController),它包含了执行共同操作的方法,其他的控制器类(例如ControllerA和ControllerB)继承这个控制器父类。图1显示了控制器父类和控制器子类的关系。

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
图1 控制器父类和控制器子类的关系

继承是提高控制器类的代码可重用性的有效手段,但是它有一个缺陷,那就是由于Java语言不支持多继承,当控制器类继承了一个控制器父类后,就不能再继承其他的类。

Spring MVC框架提供了另一种方式来为多个控制器类提供共同的方法:利用@ControllerAdvice注解来定义一个控制器增强类。

控制器增强类并不是控制器类的父类。在程序运行时,Spring MVC框架会把控制器增强类的方法代码块动态注入到其他控制器类中,通过这种方式来增强控制器类的功能。图2显示了控制器增强类(例如MyControllerAdvice)和控制器类的关系。

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
图2 控制器增强类和控制器类的关系

以下例程1的MyControllerAdvice类的setColors()方法向Model中加入一个colors属性。

例程1 MyControllerAdvice.java
package mypack;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.*;

@ControllerAdvice
public class MyControllerAdvice {

  @ModelAttribute(name = "colors")
  public Map<String,String> setColors() {
    HashMap<String, String> colors = new HashMap<String,String>();
    colors.put("RED", "红色");
    colors.put("BLUE", "蓝色");
    colors.put("GREEN", "绿色");
    return colors;
  }
}

当程序运行时,Spring MVC框架会把MyControllerAdvice类的setColors()方法动态注入到其他控制器类中,因此其他控制器类自动拥有了该方法。例如在TestAttributeController类中可以直接访问Model中的colors属性:

@RequestMapping(value="/testColor")
public String testColor(
      @ModelAttribute("colors") Map<String,String> colors,
      @ModelAttribute("userName") String name){

  System.out.println(name+"'s favourite color:"+colors.get("RED"));
  return "result";
}

通过浏览器访问以下URL:
http://localhost:8080/helloapp/testColor?name=Tom

testColor()方法会在服务器端打印“TOM's favourite color:红色”。

默认情况下,@ControllerAdvice注解用来增强当前Web应用中所有控制器类的功能。此外,它的assignableTypes属性和basePackages属性用来指定需要增强功能的控制器类:

//增强PersonController和TestAttributeController的功能
@ControllerAdvice(assignableTypes={PersonController.class,
                                         TestAttributeController.class})
public class MyControllerAdvice1{……}

//增强mypack包和net.javathinker包中的控制器类的功能
@ControllerAdvice(basePackages ={"mypack","net.javathinker"})
public class MyControllerAdvice2{……}

程序猿的技术大观园:www.javathinker.net


  Java面向对象编程-->面向对象开发方法概述之UML语言(下)
  JavaWeb开发-->在Web应用中访问Web服务
  JSP与Hibernate开发-->持久化层的映射类型
  Java网络编程-->用Swing组件展示HTML文档
  精通Spring-->
  Vue3开发-->绑定CSS样式
  【Vue.js技术专题】Vue组件的命名规则
  【Vue.js技术专题】路由导航中抓取数据
  【Vue.js技术专题】自定义指令范例:v-drag指令
  【Spring Cloud Alibaba专题】按照集群模式搭建Redis集群
  【Java基础编程专题】浮点数的格式化以及运算精度
  【持久化专题】为什么JPA和Hibernate的持久化方法都抛出运行...
  【Spring专题】控制器对象的生命周期
  视频:我的Java课堂总动员,带领小白们走马观花看Java江湖
  【持久化专题】用@Formula注解映射派生属性
  【持久化专题】@Access注解设定Hibernate访问类的属性的方式
  【持久化专题】FetchType.LAZY延迟检索策略
  【持久化专题】通过JPA API调用存储过程
  【Java网络编程专题】用Apache FTPClient在FTP服务器上创建目...
  【Java网络编程专题】用Java套接字编写基本的客户/服务器程序
  【持久化专题】比较JPA的EntityManager接口与Hibernate的Ses...
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。