Struts2-技术内幕(源码分析)——第6章OGNL.docx
第6章灵丹妙药——OGNL,数据流转的催化剂
6.1架起数据沟通的桥梁——表达式引擎
表达式引擎到底是如何与Web开发中的MVC模式关联起来的呢?要解开这一疑团,我们还是得回到MVC模式自身,重新审视MVC模式在运转过程中的困境,再看看引入表达式引擎之后是否能够真正帮助我们解决这些开发中的困境。
数据流转的困境
什么是数据流转的困境?数据为什么会流转?数据的流转又会遇到什么困境?在答复这些问题之前,我们必须首先了解一个事实:
【结论】有一股神秘的力量在MVC的各个模块中进行流转,并且它在不同的MVC层次中表现出不同的形式和状态。
我们不妨用一段简单的Struts2程序来证明这一点。这里依然选择Registration作为业务场景,其源代码如代码清单6-1、代码清单6-2和代码清单6-3所示。
代码清单6-1User.java
publicclassUser{
privateStringname;
privateStringpassword;
//省略了setter与getter方法
}
代码清单6-2user.jsp
formmethod=postaction=/registration.action
username:inputtype=textname=value=downpour/
password:inputtype=passwordname=user.passwordvalue=pass/
inputtype=submitvalue=submit/
/form
代码清单6-3UserAction.java
publicclassUserActionimplementsAction{
privateUseruser;
publicStringexecute(){
//可以直接在这里使用user对象,因为它已经被作为传入的参数了
returnsuccess;
}
//省略了setter方法与getter方法
}
这是一个简单的Struts2入门程序。仔细观察其中的运转细节就会发现,User是贯穿整个流转过程的数据载体,鉴于它的特殊作用,我们通常将User称之为数据模型〔Model〕。我们发现,User这个数据模型在不同的MVC模块中表现出不同的形式:
?View层——表现为字符串展现
在这里,View层的数据模型将遵循协议,因而它没有数据类型的概念。所有数据在页面上的表现都是一个个扁平的、不带数据类型的字符串,无论数据结构有多复杂,数据类型有多丰富,到了展示的时候,全都一视同仁地当作字符串在页面上展现出来。数据在传递时,任何数据都被当作字符串或者字符串的数组来进行。
?Controller层——表现为Java对象
在Controller层,数据模型遵循Java的语法和数据结构。所有数据载体在Java世界中可以表现为丰富的数据结构和数据类型,你可以自行定义喜欢的类,在类与类之间进行继承、嵌套。我们通常会把这种模型称之为对象树。数据在传递时,将以对象的形式进行。
【结论】数据在不同的MVC层次上,扮演的角色和表现形式不同。这是由于协议与Java的面向对象性之间的不匹配造成的。
如果我们要数据在View层〔页面〕和Java世界中互相流转传递,就会在“字符串”与“对象树”之间存在不匹配性。这个不匹配性源于Web是一个“弱类型”的平台,Web的目标是展示内容,而Java却是一个具有丰富数据类型的“强类型”的平台,目标是处理复杂的逻辑。同一个对象,在“弱类型”的平台和一个“强类型”的平台之间交互,就必须有一个非常重要的“翻译”角色解决这种“不匹配”。这个角色,就是我们所说的表达式引擎,它充当着桥梁作用,保证数据能够顺利地在MVC的各个层次进行流转。
Java对象与其他数据形式的匹配
在我们的日常开发中,不仅要面对Java世界的对象,同时还要面对各种其他的数据元素表现形式〔XML、HTML、关系型数据库、JSON等〕。这种情况下,我们总是采用一些工具来帮助解决不匹配的问题。例如,我们使用Hibernate或者myBatis这样的持久层框架来处理Java对象与关系型数据库的匹配。
数据访问的困境
数据模型〔Model〕除了表现出流动性的特征以外,我们同时更加关心数据的内容。在Web环境中,我们时不时会需要在MVC的任何执行层次对数据的内容进行访问。在上一节中,我们已经讲到,数据模型在MVC的不同层次的表现形式以及所遵循的协议都完全不同,因而在MVC的不同层次,我们进行数据访问的具体方式也不同。
数据访问的困境,主要还是来源于数据模型在某些层次的展现缺乏足够的表现力。例如,在View层,既没有数据类型的