spring mvc:注解@ModelAttribute妙用
在Spring mvc中,注解@ModelAttribute是一个非常常用的注解,其功能主要在两方面:
- 运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中,便于View层使用;
 - 运用在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中;
 
一般开发中,第一种用法居多,本次我将使用第二种用法以期节省controller层的一些代码:
目前使用spring mvc开发的controller层方法一般类似于:
  @RequestMapping("/{encodeId}/detail")
  public String detail(ModelMap model, @PathVariable String encodeId) {
     .....
  }
几乎在每一个@RequestMapping标注的方法的参数中都会有 ModelMap model的参数,既然这是一个大概率事件,为什么不可以像注入request那样,直接在类的开始使用@Resource进行自动注入呢?
另外一个,就是response,response也不能像request那样进行自动注入。
类似的可能还有很多,既然这些都是controller层常用的代码,如果能将其在一个basecontroller层自动注入,然后controller层继承这个basecontroller,那样就没有必要再@RequestMapping标注的方法中写上这些参数,使得参数个数减少,清晰。
我的思路正是使用@ModelAttribute注解,编写一个basecontroller类,预定义一些项目中controller层常用的对象,如下:
@Resource
protected HttpServletRequest request; protected ModelMap model; protected HttpServletResponse response;
request不用解释,可以直接使用@Resource直接注入,response和model的注入方式如下:
/**
* 设置response
*
* @param response
*/
@ModelAttribute
private final void initResponse(HttpServletResponse response) {
this.response = response;
} /**
* 设置model
*
* @param model
*/
@ModelAttribute
private final void initModelMap(ModelMap model) {
this.model = model;
}
spring在执行@RequestMapping前会执行上述方法,spring会和平常一样,每次请求重新生成一个model和response,然后注入到方法的参数中,这样就变相在继承了这个basecontroller的controller中自动注入了response和model,在这个controller层中再也不必每次写ModelMap和response参数,整体代码整洁了不少。
我在项目中这样使用暂无问题,如果哪位高手知道这种做法会有弊端或者有更好的方法,求指正!
修正:
非常感谢eBusinessMan的提醒,确实有可能在spring mvc单例模式下会出现访问对象不一致的情况,为了防止该问题,而又能保持这种代码的简洁性以及确保使用spring mvc性能问题不太严重,我决定使用ThreadLocal来处理。(后期验证是否会出现该问题在本文进行补充)
(验证结果:request采用spring的自动注入方式是线程安全的,response、model是不安全的,采用ThreadLocal可以解决该问题)
request对象不再使用注解自动注入(也可以继续使用注解方式注入),而使用同response和model初始化的方式,取消request、response、model三个类变量,具体如下:
   private static final ThreadLocal<HttpServletRequest> requestContainer = new ThreadLocal<HttpServletRequest>();
   private static final ThreadLocal<HttpServletResponse> responseContainer = new ThreadLocal<HttpServletResponse>();
   private static final ThreadLocal<ModelMap> modelContainer = new ThreadLocal<ModelMap>();
     /**
      * 初始化response
      *
      * @param response
      */
     @ModelAttribute
     private final void initResponse(HttpServletResponse response) {
         responseContainer.set(response);
     }
     /**
      * 获取当前线程的response对象
      *
      * @return
      */
     protected final HttpServletResponse getResponse() {
         return responseContainer.get();
     }
     /**
      * 初始化request
      *
      * @param request
      */
     @ModelAttribute
     private final void initRequest(HttpServletRequest request) {
         requestContainer.set(request);
     }
     /**
      * 获取当前线程的request对象
      *
      * @return
      */
     protected final HttpServletRequest getRequest() {
         return requestContainer.get();
     }
     /**
      * 设置model
      *
      * @param model
      */
     @ModelAttribute
     private final void initModelMap(ModelMap model) {
         modelContainer.set(model);
     }
     /**
      * 获取当前线程的modelMap对象
      *
      * @return
      */
     protected final ModelMap getModelMap() {
         return modelContainer.get();
     }
spring mvc:注解@ModelAttribute妙用的更多相关文章
- Spring MVC 中 @ModelAttribute 注解的妙用
		
Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...
 - Spring MVC注解的一些案列
		
1. spring MVC-annotation(注解)的配置文件ApplicationContext.xml <?xml version="1.0" encoding=& ...
 - spring mvc(注解)上传文件的简单例子
		
spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationConte ...
 - spring mvc 注解入门示例
		
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...
 - spring mvc 注解示例
		
springmvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
 - 关于Spring mvc注解中的定时任务的配置
		
关于spring mvc注解定时任务配置 简单的记载:避免自己忘记,不是很确定我理解的是否正确.有错误地方望请大家指出. 1,定时方法执行配置: (1)在applicationContext.xml中 ...
 - spring mvc  注解@Controller @RequestMapping  @Resource的详细例子
		
现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...
 - spring mvc之@ModelAttribute注解
		
1.@ModelAttribute注释void返回值的方法 @Controller public class HelloModelController { @ModelAttribute public ...
 - Spring MVC 注解[转]
		
[学习笔记]基于注解的spring3.0.x MVC学习笔记(九) 摘要: 本章节,仅为@SessionAttributes的功能扩展介绍介绍,结合@requestparam注解进行简易无数据库分页. ...
 
随机推荐
- 【附答案】Java 大数据方向面试题,你会几个?
			
1.Collection 和 Collections的区别. Collections是个java.util下的类,它包含有各种有关集合操作的静态方法. Collection是个java.uti ...
 - Linux系统C语言socket tcp套接字编程
			
1.套接字的地址结构: typedef uint32_t in_addr_t; //32位无符号整数,用于表示网络地址 struct in_addr{ in_addr_t s_addr; //32位 ...
 - ABP+AdminLTE+Bootstrap Table权限管理系统第十节--AdminLTE模板菜单处理
			
上节我们把布局页,也有的临时的菜单,但是菜单不是应该动态加载的么?,所以我们这节来写菜单.首先我们看一下AdminLTE源码里面的菜单以及结构. <aside class="main- ...
 - 基于ZYNQ的SOC——Hellow_World实验
			
ZYNQ是一款SOC芯片,之前使用VGA做过的实验只是PL(Programmable Logic)部分,而ZYNQ最突出的功能,就是内部的双核Cortex-A9,所以从现在开始我将学习ZYNQ的SOC ...
 - python--代码统计小程序
			
有人说,大学生在校期间要码够10W行代码,也有人说,看的不是写代码的行数,而是修改代码的行数... 不管谁说,说的人都挺牛的 咳,首先给自己定个小目标吧,5W行代码!成天写代码,啥时候到5W呢?为了更 ...
 - hdu--1711--kmp应用在整形数组--Number Sequence
			
/* Name: hdu--1711--Number Sequence Author: shen_渊 Date: 16/04/17 19:58 Description: 第一次知道,KMP能用在整形数 ...
 - Locust性能测试工具的安装及实际应用
			
一.安装Locust 安装Locust之前先安装的库:gevent库:第三方库,gevent为python提供了比较完善的协程支持.使用gevent,可以获得极高的并发性能. pip install ...
 - U盘安装Fedora 24时出现的几个问题及解决办法
			
电脑中原有Win10 1. /dev/disk/by-label/Fedora-WS-LiveCD - does not exist 用UltraISO来制作启动盘后,会把U盘盘符改为Fedora-W ...
 - python之禅  the zen of python
			
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is ...
 - 6,EasyNetQ-基于Topic的路由
			
RabbitMQ具有非常酷的功能,基于主题的路由,允许订阅者基于多个标准过滤消息. 主题是与邮件一起发布的点分隔的单词列表. 例子是"stock.usd.nyse"或"b ...