数据的流转
在MVC设计模式中,数据模型Model往往在不同的模块中表现出不同的形式:
View层——表现为字符串展现
在这里,View层的数据模型将遵循Http协议,因而它没有数据类型的概念。所有数据在页面上的表现都是一个个扁平的、不带数据类型的字符串,无论数据结构有多复杂,数据类型有多丰富,到了展示的时候,全都一视同仁地当做字符串在页面上展现出来。数据在传递的时,任何数据都被当做字符串或者字符串的数组来进行。Controller层——表现为Java对象
在Controller层,数据模型遵循Java的语法和数据结构。所有数据载体在Java世界中可以表现为丰富的数据结构和数据类型,你可以自定义喜欢的类,在类与类之间进行继承、嵌套。我们通常会把这种模型称之为对象树。数据在传递时,将以对象的形式进行。
结论 数据在不同的MVC层次上,扮演的角色和表现形式不同。这是由于Http协议与Java的面向对象性之间的不匹配造成的
数据访问的困境
数据模型(Model)除了表现出流动性的特征以外,我们同时更加关心数据的内容。在Web环境中,我们时不时会需要在MVC的任何执行层次对数据的内容进行访问。而数据模型在MVC的不同层次的表现形式以及所遵循的协议都完全不同,所以我们在MVC的不同层次,进行数据访问的具体方式也不同。
数据访问的困境,主要还是来源于数据模型在某些层次的展现缺乏足够的表现力。 例如,在View层,既没有数据类型的概念,也没有数据结构的概念。无论数据自身的结构有多复杂,一旦对外展现,都最终转化为统一的字符串形式。在这种情况下,我们就需要建立一种符号化的规则,使之与复杂而丰富的Java类型对应起来,这种规则就是表达式引擎的雏形。
在数据流转的过程中, 我们可以看到两个截然不同的方向:
从View层到Controller层
这个方向的数据的流转所强调的,是能够保证一个扁平而分散的数据能以一定的规则设置到Java世界的对象树中去。同时,能够聪明地进行由字符串类型到Java中各个类型的转化。从Controller到View层
这个方向的数据流转所强调的,是保证在View层能够以某些简易的规则对Java的对象树进行访问。同时,在一定程度上控制对象树中的数据的显示格式。——我们这里所说的数据访问,其实指的就是数据从Controller层流转到View层的过程。在这个过程中,表达式所起的作用,就是建立起访问规则与Java对象树之间的联系。在这个方面有不少成熟的方案,如JSTL、模板语言等等,但无论是什么样的方案,其实现的基础都是一致的,那就是表达式引擎。
表达式引擎
表达式引擎的引入,帮助我们完成规则化的表达式与Java对象的互相转化。,因而它成为架起MVC各个模板之间数据沟通的桥梁。
发挥我们的主观能动性来思考一下,数据在交互的过程中到底会遇到什么样的困境,这些困境将成为我们选择和使用表达式引擎的依据:
表达式引擎应该能处理表达式与对象之间的映射关系,这种映射关系应是双向的。
表达式引擎应该能支持丰富多样的表达式语法计算
表达式引擎应该能支持必要的数据类型转换
在Java世界中, 有许多优秀的表达式引擎。OGNL在内部实现机制与设计原理上有许多亮点,因而Struts2选择了OGNL作为其依赖的表达式引擎,并在OGNL的基础上做了一定的扩展,使OGNL的应用更加丰富。
参考:整理归纳自《struts2技术内幕——深入解析struts2架构设计与实现原理》