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操作,接下来我们介绍一下返回值的处理操作.同样返回值的操作操作也 ...
随机推荐
- Resource 的 IsSealed 问题
WFP 的 Generic.xaml ,App.xaml 等中的资源会被调用 Freezable. 在后台对该资源进行修改等操作会被提示.资源为密封对象. 如果,确定需要在后台对资源进行修改. 则需要 ...
- 如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?
自从HTML5出来以后,使用WebSocket通信就变得火热起来,基于WebSocket开发的手机APP和手机游戏也越来越多.我的一些开发APP的朋友,开始使用WebSocket通信,后来觉得通信不够 ...
- Redis常用命令--Lists
List是一个双向链表,按照插入顺序排序,可以添加一个元素到头部或者尾部.当对一个空key执行插入操作的时候会创建一个新表. 如果要清空列表,则会杀出对应的key空间. 在List中保存了头节点和未节 ...
- tarjan——cogs 1298 通讯问题
1298. 通讯问题 ★ 输入文件:jdltt.in 输出文件:jdltt.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 一个篮球队有n个篮球队员,每个队员 ...
- 【NOIP2013TG】solution
链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%2C30 D1T1:转圈游戏(circle) 题意: ...
- 【USACO】 奶牛会展
题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由于负的智商或情商会造成 ...
- WebDNN:Web浏览器上最快的DNN执行框架
WebDNN:Web浏览器上最快的DNN执行框架 为什么需要WebDNN? 深层神经网络(DNN)在许多应用中受到越来越多的关注. 然而,它需要大量的计算资源,并且有许多巨大的过程来设置基于执行环境的 ...
- Git/GitHub SSH配置
生成 SSH 公钥 如前所述,许多 Git 服务器都使用 SSH 公钥进行认证. 为了向 Git 服务器提供 SSH 公钥,如果某系统用户尚未拥有密钥,必须事先为其生成一份. 这个过程在所有操作系统上 ...
- Window下使用ftp命令往Linux中发送文件
操作步骤:首先,切换到文件目录1.ftp ip地址2.连接成功后,输入正确的用户名和密码.3.binary(表示以二进制的格式传送)4.put/get 文件名(或文件的绝对路径) 退出:bye
- range和xrange的区别详解
两种用法介绍如下:1.range([start], stop[, step])返回等差数列.构建等差数列,起点是start,终点是stop,但不包含stop,公差是step.start和step是可选 ...