spring mvc中注解@ModelAttribute的妙用分享
作者:雨中漫步,惟情而已 发布时间:2022-09-15 13:53:25
前言
本文主要给大家介绍了关于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();
}
来源:http://www.cnblogs.com/liaochong/p/spring_modelattribute.html


猜你喜欢
- 本文实例为大家分享了Android弹性滑动类Scroller的具体代码,供大家参考,具体内容如下Scroller是什么 Scroller就是
- 为什么使用Swagger 在实际开发中我们作为后端总是给前端或者其他系统提供接口,每次写完代码之后不可避
- 看似很鸡肋其实在某些特殊场景还是比较有用的。比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value。
- 在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private私有方法。只允许我们定义publi
- 判断某字符串是否为空,为空的标准是str==null或str.length()==01.下面是StringUtils判断是否为空的示例:St
- 接上一篇写的截取电脑屏幕,我们在原来的基础上加一个选择区域的功能,实现自定义选择截图。个人比较懒,上一篇的代码就不重新设计了,就简单改一下呈
- 使用@Provider注意事项(要点)1.在Mapper接口和@InsertProvider方法类中,不要使用重载,也就是说,不要使用方法名
- 现在再回过头理解,结合自己的体会, 选用最佳的方式描述这些算法,以方便理解它们的工作原理和程序设计技巧。本文适合做java面试准备的材料阅读
- Android ViewGroup中的Scroller与computeScroll的有什么关系?答:没有直接的关系知道了答案,是不是意味着下
- 前言一般数据库的表结构都会有update_time,修改时间,因为这个字段基本与业务没有太大关联,因此开发过程中经常会忘记设置这两个字段的值
- 本文实例展示了WinForm实现为TextBox设置水印文字功能,非常实用的技巧,分享给大家供大家参考。关键代码如下:using Syste
- Java 和 Groovy 中的映射map都是非常通用的,它允许关键字key和值value为任意类型,只要继承了 Object&n
- 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关键字R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前
- 一、创建项目并导入相关依赖<dependency> <groupId>org.springframewo
- 事务挂起和事务恢复源码解读在学习spring事务的时候,一定会涉及到一个概念,无法避免的,就是事务挂起和事务恢复对于事务挂起和事务恢复,可以
- JLabel 对象可以显示文本、图像或同时显示二者。可以通过设置垂直和水平对齐方式,指定标签显示区中标签内容在何处对齐。默认情况下,标签在其
- 最近参与了开发一款旅行APP,其中包含实时聊天和动态评论功能,终于耗时几个月几个伙伴完成了,今天就小结一下至于实时聊天功能如果用户不多的情况
- 本文实例讲述了Android ActionBar搜索功能用法。分享给大家供大家参考,具体如下:使用ActionBar SearchView时
- MyBatis 获取子类的属性这里有个model类:基类public class user { pu
- import java.util.concurrent.Semaphore;public class ThreeThread {