springMVC4(7)模型视图方法源代码综合分析

在完整web开发中。springMVC主要充当了控制层的角色。它接受视图层的请求。获取视图层请求数据,再对数据进行业务逻辑处理。然后封装成视图层须要的模型数据,再将数据导向到jsp等视图界面。

在前面,我们通过对@RequestMapping和方法入參绑定的分析,完毕了视图层->控制层的数据交接,然后业务逻辑处理主要由Service层进行。那么接下来非常关键的就是,怎样将视图数据导向到特定的视图中。

广泛意义上,视图,并不是是单指前端界面如jsp\html等。我们可能须要给安卓、IOS等写后台接口、因前后端分离而放弃视图界面导向如对前端ajax请求的纯数据流输出等。

这时,我们的视图能够为json视图、xml视图、乃至PDF视图、Excel视图等

springMVC为我们提供了多种途径输出模型数据:

输出途径 功能说明
ModelAndView 将处理方法返回类型设为ModelAndView。里面封装了我们的模型数据,同一时候指明了视图导向。

@modelAttribute 方法入參标注改注解后,入參的对象就会放到数据模型中。

Map及Model 入參为org.springframework.ui.Model或org.springframework.ui.ModelMap或java.util.Map时,方法返回时会将Map中的数据自己主动加入到模型中
@SessionAttributes 将模型中的某个属性暂存到HttpSession中,以便多个请求之间完毕属性共享

以下我们主要介绍ModelAndView

ModelAndView(以下简称MAV)就像它的名字一样。既包括了模型数据又包括视图信息。我们返回一个MAV。springMVC就会将模型数据转发给相应的视图界面。

在学习ModelAndView的用法前。我们先用肢解的方法学习其两个重要组成部分

1. model

model是一个接口,我们能够简单地将model的实现类理解成一个Map,将模型数据以键值对的形式返回给视图层使用。在springMVC中,每一个方法被前端请求触发调用前,都会创建一个隐含的模型对象,作为模型数据的存储容器。

这是一个Request级别的模型数据。我们能够在前端页面如jsp中通过HttpServletRequest等相关API读取到这些模型数据。

在model中。定义有例如以下经常使用接口方法:

    /**
     * 加入键值属性对
     */
    Model addAttribute(String attributeName, Object attributeValue);

    /**
     * 以属性的类型为键加入属
     */
    Model addAttribute(Object attributeValue);

    /**
     * 以属性和集合的类型构造键名加入集合属性,假设有同类型会存在覆盖现象
     */
    Model addAllAttributes(Collection<?> attributeValues);

    /**
     * 将attributes中的内容拷贝到当前的model中
     * 假设当前model存在同样内容。会被覆盖
     */
    Model addAllAttributes(Map<String, ?> attributes);

    /**
     * 将attributes中的内容拷贝到当前的model中
     * 假设当前model存在同样内容,不会被覆盖
     */
    Model mergeAttributes(Map<String, ?> attributes);

    /**
     * 推断是否有相应的属性值
     */
    boolean containsAttribute(String attributeName);

    /**
     * 将当前的model转换成Map
     */
    Map<String, Object> asMap();

假设我们加入的属性没有指定键名。我们称之为匿名数据绑定,它们遵循例如以下规则:

1. 对于普通数据类型,我们直接以类型(第一字母小写)作为键值

2. 对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List生成的模型对象属性名为“stringList”,List生成的模型对象属性名为“userModelList”。

在ModelAndView中,我们很多其它的是直接操作modelMap和Map来完毕我们的模型參数准备就可以。modelMap继承自java.util.LinkedHashMap。

它在LinkedHashMap的基础上,新增了非常多便利的构造方法如:

public ModelMap(String attributeName, Object attributeValue) {
    addAttribute(attributeName, attributeValue);
}
public ModelMap addAllAttributes(Map<String, ?

> attributes) {
    if (attributes != null) {
        putAll(attributes);
    }
    return this;
}

使用这些构造方法能进一步简化我们的模型数据封装。

2. view

view也是一个接口,它表示一个响应给用户的视图如jsp文件,pdf文件,html文件。

它有两个接口方法:

1. String getContentType():返回视图的内容类型

2. void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception:依据给定模型和web资源定义视图的渲染形式。

view接口有众多的实现类,例如以下图所看到的:

在spring中。通过ViewResolver来解析相应View实例的行为。 它的定义相当简单:

public interface ViewResolver {
    //通过view name 解析View
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

spring为我们提供ViewResolver实现类用来解析不同的view:

在我们最開始配置springMVC核心文件时,就用到了InternalResourceViewResolver,它是一个内部资源视图解析器。

会把返回的视图名称都解析为 InternalResourceView 对象。 InternalResourceView 会把 Controller 处理器方法返回的模型属性都存放到相应的 request 属性中。然后通过 RequestDispatcher 在server端把请求 forword 重定向到目标 URL。

以下我们来看配置实例:

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property><!-- 前缀,在springMVC控制层处理好的请求后,转发配置文件夹下的视图文件 -->
    <property name="suffix" value=".jsp"></property><!-- 文件后缀,表示转发到的视图文件后缀为.jsp -->
</bean>

解析完Model and(和) View后,再来看我们的ModelAndView:

public class ModelAndView {

    //视图成员
    private Object view;

    //模型成员
    private ModelMap model;

    //是否调用clear()方法清空视图和模型
    private boolean cleared = false;

    /**
     * 空构造方法
     */
    public ModelAndView() {
    }

    /**
     * 简便地使用视图名生成视图,详细解析由DispatcherServlet的视图解析器进行
     */
    public ModelAndView(String viewName) {
        this.view = viewName;
    }

    /**
     * 指定一个视图对象生成视图
     */
    public ModelAndView(View view) {
        this.view = view;
    }

    /**
     * 指定视图名同一时候绑定模型数据。这里模型数据以追加的形式加入在原来的视图数据中
     */
    public ModelAndView(String viewName, Map<String, ?

> model) {
        this.view = viewName;
        if (model != null) {
            getModelMap().addAllAttributes(model);
        }
    }

    /**
     * 指定一个视图对象同一时候绑定模型数据。这里模型数据以追加的形式加入在原来的视图数据中
     */
    public ModelAndView(View view, Map<String, ?> model) {
        this.view = view;
        if (model != null) {
            getModelMap().addAllAttributes(model);
        }
    }

    /**
     * 简便配置:指定视图名,同一时候加入单个属性
     */
    public ModelAndView(String viewName, String modelName, Object modelObject) {
        this.view = viewName;
        addObject(modelName, modelObject);
    }

    /**
     * 简便配置:指定一个视图对象,同一时候加入单个属性
     */
    public ModelAndView(View view, String modelName, Object modelObject) {
        this.view = view;
        addObject(modelName, modelObject);
    }

    /**
    * 设置当前视图名
    */
    public void setViewName(String viewName) {
        this.view = viewName;
    }

    /**
     * 获取视图名。假设当前视图属性为view而非名字(String)则返回null
     */
    public String getViewName() {
        return (this.view instanceof String ? (String) this.view : null);
    }

    /**
     * 设置当前视图对象
     */
    public void setView(View view) {
        this.view = view;
    }

    /**
     * 获取视图,假设非view实例,则返回null
     */
    public View getView() {
        return (this.view instanceof View ? (View) this.view : null);
    }

    /**
     * 推断当前视图是否存在
     */
    public boolean hasView() {
        return (this.view != null);
    }

    /**
     * 获取模型Map。假设为空,则新建一个
     */
    public ModelMap getModelMap() {
        if (this.model == null) {
            this.model = new ModelMap();
        }
        return this.model;
    }

    /**
     * 同getModelMap
     */
    public Map<String, Object> getModel() {
        return getModelMap();
    }

    /**
     * 加入单个键值对属性
     */
    public ModelAndView addObject(String attributeName, Object attributeValue) {
        getModelMap().addAttribute(attributeName, attributeValue);
        return this;
    }

    /**
     * 以属性类型为键加入属性
     */
    public ModelAndView addObject(Object attributeValue) {
        getModelMap().addAttribute(attributeValue);
        return this;
    }

    /**
     * 将Map中的全部属性加入到成员属性ModelMap中
     */
    public ModelAndView addAllObjects(Map<String, ?> modelMap) {
        getModelMap().addAllAttributes(modelMap);
        return this;
    }

    /**
     * 清空视图模型。并设为清空状态
     */
    public void clear() {
        this.view = null;
        this.model = null;
        this.cleared = true;
    }

    /**
     * 推断是否为不含视图和模型
     */
    public boolean isEmpty() {
        return (this.view == null && CollectionUtils.isEmpty(this.model));
    }

}
时间: 2024-10-11 11:35:18

springMVC4(7)模型视图方法源代码综合分析的相关文章

学习模型-视图-控制器MVC模式

MVC简介: MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: Model(模型)表示应用程序核心(比如数据库记录列表). View(视图)显示数据(数据库记录). Controller(控制器)处理输入(写入数据库记录). MVC 模式同时提供了对 HTML.

模型-视图 教程

模型/视图 教程 每一个UI开发者都应该了解Model/View编程,这篇教程的目标就是对这个主题提供一个容易理解的介绍. Table, list and tree 窗口部件都是在图形用户界面中常用的组件.这些窗口部件能够通过两种不同的方式访问他们的数据.传统方式是通过窗口部件的内部容器来存储数据.这种方法很直观,然而在一些大型应用中,通常会引起数据同步问题.第二张方法是Model/View编程,用这种方法窗口部件不需要维护内部的数据容器.他们通过一个标准化的接口访问外部数据,因此避免了数据复制

WebGL或OpenGL关于模型视图投影变换的设置技巧

目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在问题 1. 具体实例 看了不少的关于WebGL/OpenGL的资料,笔者发现这些资料在讲解图形变换的时候都讲了很多的原理,然后举出一个特别简单的实例(坐标是1.0,0.5的那种)来讲解.确实一看就懂,但用到实际的场景之中就一脸懵逼了(比如地形的三维坐标都是很大的数字).所以笔者这里结合一个具体的实例

Qt 学习之路:模型-视图高级技术

PathView PathView是 QtQuick 中最强大的视图,同时也是最复杂的.PathView允许创建一种更灵活的视图.在这种视图中,数据项并不是方方正正,而是可以沿着任意路径布局.沿着同一布局路径,数据项的属性可以被更详细的设置,例如缩放.透明度等. 使用PathView首先需要定义一个代理和一个路径.除此之外,PathView还可以设置很多其它属性,其中最普遍的是pathItemCount,用于设置可视数据项的数目:preferredHighlightBegin.preferred

Qt模型/视图中的data和headerData

QAbstractItemModel QAbstractItemModel是一个抽象类,该抽象类未实现的纯虚方法有 QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex & parent = QModelIndex()) const [pure virtual] QModelIndex QAbstractItemModel::parent(const QModelIndex & index)

OPENCV学习笔记3-4_使用模型-视图-控制器设计应用程序

此节介绍的架构模式(MVC),将联合使用模型-视图-控制器(Model-View-Controller)三个模式以及其他的类.其清晰地分离程序中的逻辑部分与用户交互部分.此节将使用MVC模式构建一个基于QT的图形界面应用程序. 模型包含关于应用程序的信息,它拥有所有由应用程序处理的数据.当出现新的数据,它将告知控制器,后者要求视图来显示结果.通常模型将集合多个算法,它们很有可能按照策略模式进行实现. 视图职责之一是发送用户的命令到控制器.当新数据可用时,它会刷新自己以显示新的信息. 控制器将视图

Qt MVC设计模式:子类化抽象模型的方法

模型子类化参考 模型的子类需要提供很多在QAbstractItemModel中定义的虚函数的实现.需要实现的方法的数量取决于你想创建的子类的风格--它提供一个简单的列表视图,还是一个表格视图,或者是一个复杂的层次视图.从QAbstractListModel和QAbstractTableModel继承的子类可以直接利用这两个类的许多默认的虚函数. 子类中需要实现的方法可以分为三种: 1. 处理项数据:所有的模型需要实现方法来保证视图和委托能够查询模型的尺寸.检测每个项以及返回其中的数据. 2. 浏

[框架模式]经典的模型视图控制器模式MVC

参考:<设计模式> http://blog.csdn.net/u010168160/article/details/43150049 百度百科 引言: Model(模型)是应用程序中用于处理应用程序数据逻辑的部分. 通常模型对象负责在数据库中存取数据. View(视图)是应用程序中处理数据显示的部分. 通常视图是依据模型数据创建的. Controller(控制器)是应用程序中处理用户交互的部分. 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据. MVC 分层有助于管理复杂的应用程

【GISER&amp;&amp;Painter】Chapter02:WebGL中的模型视图变换

上一节我们提到了如何在一张画布上画一个简单几何图形,通过创建画布,获取WebGLRendering上下文,创建一个简单的着色器,然后将一些顶点数据绑定到gl的Buffer中,最后通过绑定buffer数据,提供buffer中顶点数据的情况,执行渲染绘制方法,将数据结果从buffer中刷新到帧缓存中.整个流程十分清晰明了,可是通过对比原来OpenGL中的整个流程,我们会发现其中还缺少了一些很重要的处理步骤,虽然我们创建了属于自己的着色器,可并没有对顶点数据进行类似于顶点处理管线中的模型视图变换.透视