springMVC源码分析--ModelAndViewContainer和ModelMap
defaultModel是默认使用的Model,后者用于传递redirect时的参数,我们在处理中使用了Model或ModelMap时,ArgumentResolver会传入defaultModel,它是BindingAwareModelMap类型,既继承了ModelMap又实现了Model接口,所以在处理器中使用Model或者ModelMap其实使用的是同一个对象,Map参数传入的也是这个对象。处理器中RedirectAttributes类型的参数ArgumentResolver会传入redirectModel,它实际上是RedirectAttributeModelMap类型。
ModelAndViewContainer中其实就是一个ModelMap,一系列的操作都是基于ModelMap的。
public class ModelAndViewContainer { private boolean ignoreDefaultModelOnRedirect = false; //视图,可以是实际视图也可以是String类型的逻辑视图 private Object view; //默认使用的Model private final ModelMap defaultModel = new BindingAwareModelMap(); //redirect类型的Model private ModelMap redirectModel; private boolean redirectModelScenario = false; //用于设置SessionAttribute使用完的标志 private final SessionStatus sessionStatus = new SimpleSessionStatus(); //请求是否已经处理完成的标志 private boolean requestHandled = false; public void setIgnoreDefaultModelOnRedirect(boolean ignoreDefaultModelOnRedirect) { this.ignoreDefaultModelOnRedirect = ignoreDefaultModelOnRedirect; } //设置视图名称 public void setViewName(String viewName) { this.view = viewName; } public String getViewName() { return (this.view instanceof String ? (String) this.view : null); } public void setView(Object view) { this.view = view; } public Object getView() { return this.view; } public boolean isViewReference() { return (this.view instanceof String); } public ModelMap getModel() { if (useDefaultModel()) { return this.defaultModel; } else { return (this.redirectModel != null) ? this.redirectModel : new ModelMap(); } } //和model相关的处理方法 /* * 假设redirectModelScenario = R ,ignoreDefaultModelOnRedirect = I ,(redirectModel == null)= M * 那么(R, I, M)共有8中组合情况,useDefaultModel返回false(也就是使用redirectModel)只有三种情况: * (1,1,0)、(1,1,1)、(1,0,0) * a:如果同时设置了redirectModelScenario和ignoreDefaultModelOnRedirect为true,那么无论redirectModel * 是否为null,都会使用redirectModel; * b:如果设置了redirectModelScenario为true,而ignoreDefaultModelOnRedirect为false,同时redirectModel * 为null,那么也会使用redirectModel; */ private boolean useDefaultModel() { return (!this.redirectModelScenario || (this.redirectModel == null && !this.ignoreDefaultModelOnRedirect)); } public ModelMap getDefaultModel() { return this.defaultModel; } public void setRedirectModel(ModelMap redirectModel) { this.redirectModel = redirectModel; } public void setRedirectModelScenario(boolean redirectModelScenario) { this.redirectModelScenario = redirectModelScenario; } public SessionStatus getSessionStatus() { return this.sessionStatus; } public void setRequestHandled(boolean requestHandled) { this.requestHandled = requestHandled; } public boolean isRequestHandled() { return this.requestHandled; } public ModelAndViewContainer addAttribute(String name, Object value) { getModel().addAttribute(name, value); return this; } public ModelAndViewContainer addAttribute(Object value) { getModel().addAttribute(value); return this; } public ModelAndViewContainer addAllAttributes(Map<String, ?> attributes) { getModel().addAllAttributes(attributes); return this; } public ModelAndViewContainer mergeAttributes(Map<String, ?> attributes) { getModel().mergeAttributes(attributes); return this; } public ModelAndViewContainer removeAttributes(Map<String, ?> attributes) { if (attributes != null) { for (String key : attributes.keySet()) { getModel().remove(key); } } return this; } public boolean containsAttribute(String name) { return getModel().containsAttribute(name); } }
ModelMap其实就是一个HashMap而已,主要用于数据的存取而已。
@SuppressWarnings("serial") public class ModelMap extends LinkedHashMap<String, Object> { public ModelMap() { } public ModelMap(String attributeName, Object attributeValue) { addAttribute(attributeName, attributeValue); } public ModelMap(Object attributeValue) { addAttribute(attributeValue); } public ModelMap addAttribute(String attributeName, Object attributeValue) { Assert.notNull(attributeName, "Model attribute name must not be null"); put(attributeName, attributeValue); return this; } public ModelMap addAttribute(Object attributeValue) { Assert.notNull(attributeValue, "Model object must not be null"); if (attributeValue instanceof Collection && ((Collection<?>) attributeValue).isEmpty()) { return this; } return addAttribute(Conventions.getVariableName(attributeValue), attributeValue); } public ModelMap addAllAttributes(Collection<?> attributeValues) { if (attributeValues != null) { for (Object attributeValue : attributeValues) { addAttribute(attributeValue); } } return this; } public ModelMap addAllAttributes(Map<String, ?> attributes) { if (attributes != null) { putAll(attributes); } return this; } public ModelMap mergeAttributes(Map<String, ?> attributes) { if (attributes != null) { for (Map.Entry<String, ?> entry : attributes.entrySet()) { String key = entry.getKey(); if (!containsKey(key)) { put(key, entry.getValue()); } } } return this; } public boolean containsAttribute(String attributeName) { return containsKey(attributeName); } }
springMVC源码分析--ModelAndViewContainer和ModelMap的更多相关文章
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
- 框架-springmvc源码分析(一)
框架-springmvc源码分析(一) 参考: http://www.cnblogs.com/heavenyes/p/3905844.html#a1 https://www.cnblogs.com/B ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)
在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...
- springMVC源码分析--页面跳转RedirectView(三)
之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...
- springMVC源码分析--HttpMessageConverter写write操作(三)
上一篇博客springMVC源码分析--HttpMessageConverter参数read操作中我们已经简单介绍了参数值转换的read操作,接下来我们介绍一下返回值的处理操作.同样返回值的操作操作也 ...
随机推荐
- 1.4WEB API 路由配置及参数传输
在没有添加路由时,webapi 的访问比较恶心,访问的时候是没有接口方法的.如果定义了同样参数的方法,它就傻傻的分不清的,为了解决这个问题,我们加上路由吧. 这是生成的api帮助文档列表,可以看到下面 ...
- 使用vue-cli快速搭建大型单页面应用开发环境
工作环境:terminal,已经全局安装了vue(可使用npm install -g vue) 全局安装vue-cli npm install -g vue-cli 创建一个基于webpack模板的项 ...
- Spring Cloud学习笔记-003
服务提供者:向注册中心注册服务 1. 新建maven工程,骨架选择quickstart,工程名称:demo-member 2. 加入相关依赖: 3. 编写服务接口: 4. 在src\main\reso ...
- Logstic回归采用sigmoid函数的原因
##Logstic回归采用sigmoid函数的原因(sigmoid函数能表示二项分布概率的原因) sigmoid函数: ![](http://images2017.cnblogs.com/blog/1 ...
- Spark RDDs vs DataFrames vs SparkSQL
简介 Spark的 RDD.DataFrame 和 SparkSQL的性能比较. 2方面的比较 单条记录的随机查找 aggregation聚合并且sorting后输出 使用以下Spark的三种方式来解 ...
- 申请安装阿里云免费SSL证书
微信小程序已经全面要求使用HTTPS服务了,还有苹果商店也是,所以,实现网站HTTPS已经很有必要.要实现HTTPS就需要一个SSL证书,证书大部分都很贵,不过也有一些免费的证书服务供个人开发者使用. ...
- OpenGL中glUniform1i使用
在OpenGL中使用glGetUniformLocation和glUniformxxx等函数时,要在之前启用对应的着色器程序,即调用glUseProgram.
- 解析spring中的BeanFactory
我们常把spring看作一个bean工厂或者ioc容器,它帮助我们负责对象的创建管理,以及对象间依赖关系的建立,还有其他的功能. 关于工厂的实现,一般来说与我们接触最多的就是BeanFactory和A ...
- Jenkins: Can't connect to Docker daemon解决办法
Jenkins安装后首次使用报错: Jenkins: Can't connect to Docker daemon 解决办法: 参照StackOverflow 添加jenkins用户到dockergr ...
- drupal8的安装
一.首先安装好linux系统虚拟机 1.在drupal官网上下载drupal包,https://www.drupal.org/download 我下载的是 https://ftp.drupal.org ...