java课件-04框架struts24ognl p本章节授课目标_第1页
java课件-04框架struts24ognl p本章节授课目标_第2页
java课件-04框架struts24ognl p本章节授课目标_第3页
java课件-04框架struts24ognl p本章节授课目标_第4页
java课件-04框架struts24ognl p本章节授课目标_第5页
已阅读5页,还剩66页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Struts2本章节授课目标Struts2框架技术OGNL技术介绍OGNL表达式与Struts2整合23OGNL简介OGNL的全称是Object

Graph

Navigation

Language(对象图导航语言),它是一种强大的表达式语言,让你通过简单一4为什么要使用OGNL视图层的表达式语言通常是用来简化数据的 操作,取代Java

代码,提供更清晰的视图层实现。例如,在JSP页面中使用JSP2.0内置的表达式语言获取request中的user对象的username属性,可以简写为:${user.username}如果换作Java

代码,则需要写为:<%@

page

language="java"

import="java.util.*,com.shinowit.User"pageEncoding=“utf-8"%><%User

user

=

(User)request.getAttribute("user");Stringusername

=

user.getUsername();out.print(username);%>和上面的EL表达式写法效果一样5为什么要使用OGNL哪 法更为简捷,相信大家已经一目了然了。既然JSP2.0已经内置了一种表达式语言,那么为什么还要学习和使用OGNL技术呢?相对于其它的表达式语言而言,OGNL的功能更为强大,它提供了很多高级而必须的特性,例如强大的类型转换功能,静态或实例方法的执行,跨集合投影(projection),以及动态lambda表达式定义等。ONGL功能示例:调用静态方法<s:property

value="@com.test.util.S@abc()">ONGL功能示例:定义集合<s:select

label="label"

name="name"list="{'name1','name2','name3'}"

value="%{'name2'}"/>6简介小结OGNL是一门表达式语言,是用来简化对象

的技术。OGNL在某些方面比JSP技术的EL表达式强大。OGNL是一门独立的技术,很多Web框架都使用到了OGNL技术,例如:Tapestry框架,注意OGNL并不是只能用于

Struts2框架的。78OGNL上下文对象OGNL表达式的计算都是围绕OGNL上下文来进行的,OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类(实现了java.util.Map接口)来表示。OGNL上下文可以包含一个或多个JavaBean对象,在这些对象中有一个是特殊的,这个对象就是上下文的根(root)对象。如果在写表达式的时候,没有指定使用上下文中的哪一个对象,那么根对象将被假定为表达式所依据的对象。最多只能设置其中一个为根(root)对象OGNL基础示例示例:演示OGNL上下文对象是Map类型的,可以向其中放入数据,演示可以指定OGNL上下文对象的根对象(root),然后在没有明确指明的情况下会

root对象属性。类定义完整代码见PPT备注10OGNL基础示例接前页一个辅助演示的工具类,用于稍微的 一下ONGL的操作过程,便于后续代码明确演示重点,不用深入研究这个类的代码。package

com.shinowit;import

ognl.Ognl;importognl.OgnlContext;import

ognl.OgnlException;public

class

OgnlExpression

{private

Object

expression;public

OgnlExpression(String

expressionString)throws

OgnlException{super();expression=Ognl.parseExpression(expressionString);}publicObjectgetExpression(){return

expression;}public

Object

getValue(OgnlContext

context,Object

rootObject)

throws

OgnlException{return

Ognl.getValue(getExpression(),context,rootObject);}publicvoid

setValue(OgnlContextcontext,Object

rootObject,Object

value)

throws

OgnlException{Ognl.setValue(getExpression(),

context,

value);}}11OGNL基础示例完整代码见PPT备注上下文对象可以像Map一样使用12OGNL基础示例说明OgnlContext就是一个Map,在Map中保存值,需要指定键(key),在写表达式的时候使用的就是键名(key名称),而不是对象名,这一点一定要注意。在Ognl上下文中,最多只能有一个根对象,如果你根对象,那么在写表达式的时候,直接写对象属性(property)就可以了;否则,你需要使用”#key”前缀,例如表达式:

#.另外需要注意的是,OGNL表达式中的属性(property)是

JavaBean的属性,应该有对应的get和set方法,而不是类中的实例变量。13OGNL基础示例二请看下面的需求,假设有如下用户对象模型:public

interface

User

{public

String

getName();public

Date

getRegisterDate();public

Customer

getCustomer();

}public

interface

Customer

{public

String

getId();

public

String

getName();public

boolean

isVip();

}publicinterface

EntCustomer

extends

Customer{

public

String

getTrustId();//组织机构代码证号}User接口中的方法getCustomer返回的数据类型为Customer或者子接口类型,即客户有可能是普通客户也有可能是企业 类型。普通客户企业客户14OGNL基础示例二对于给定的用户jack,且该用户所属客户是企业客户,那么如何获取该用户的 ?如何获取用户所属客户的名称?如何判断该用户所属客户是否是VIP客户?如何取jack所属企业的组织机构代码证号?如果采用java编码的方式应该按照如下方法操作jack.getName();jack.getCustomer().getName();jack.getCustomer().isVip();((EntCustomer)jack.getCustomer()).getTrustId();如此复杂的情况用OGNL如何处理?15OGNL基础示例二可以用如下方式取得所需要的信通过采用OGNL,息:jack.customer.vipjack.customer.trustId通过上面的示例 可以看出OGNL的表达方式与java表达方式有以下几点不同:不需关注对象类型,不需进行强制类型转换,OGNL框架会自动转换表达方式更简短和直观,直接用.操作符

即可16OGNL基础小结两个重要概念:OGNL上下文对象实现了Map接口,是一个Map类型的数据结构,可以存入多个对象。根对象OGNL上下文对象中可以放入很多个类实例对象,但是最多只能指定根对象属性或方法时可以不用写根对象的话可以简写OGNL表达式,简一个为根对象,写表达式“#key名称”的方式,即化开发过程。1718Struts2与OGNL通过前面的学习, 知道OGNL当中很重要的两个概念“上下文对象”和“根对象”:上下文对象所有OGNL表达式中要

的对象放入OGNL上下文中的,使用,上下文对象就像是一个Map。,让程序员在编程时不写#时缺省的

某时从OGNL上下文中根对象是为了简化对象个对象。Struts2框架与OGNL框架是如何整合的呢?Struts2框架如何管理OGNL上下文对象的?Struts2框架向OGNL上下文对象中都存入了哪些对象?Struts2框架设置哪一个对象作为根对象呢?19Struts2与OGNL在讲Struts2

Action类如何

非原生Servlet

API对象时介绍了一个类:ActionContext类,通过ActionContext类可以 Application对象、Session对象等。@Overridepublic

String

execute()

throws

Exception

{ActionContext

context=ActionContext.getContext();Map

request=(Map)context.get(“request”);//获得request对象Map

session=(Map)context.getS

ssion();pplication();值放到request作用域中值放到session作用域中值放到application作用域中Map

application=(Map)context.grequest.put(“user”,“admin”);//将session.put(“user”,“admin”);//将application.put(“user”,“admin”);return

SUCCESS;}OGNL上下文对象与ActionContext类有关20Struts2与OGNLcom.opensymphony.xwork2.ActionContext类中定义了一个叫做context的Map对象,所有的Application、Session等伪Servlet

API对象都放入了这个context对象中。演示:分析ActionContext代码.重点:讲解清楚application、session、valueStack等都是通过调用put和get方法存入这个Map类型的context对象中的。ActionContext类源码注意ActionContext中的context对象,通过Struts2框架的封装,OGNL的上下文对象就是这个context对象。21Struts2与OGNLStruts2中的OGNL上下文在Struts2中,OGNL上下文结构如下所示:|--

application||--session|context

map|--OgnlValueStack(root)

[

user,

action,OgnlUtil,

...

]||--request||--parameters||--attrOgnl上下文对象,位于ActionContext类中,Map类型OgnlValueStack是ValueStack接口的实现类22Struts2与OGNL可以使用“#request”

HttpServletRequest对象,“#session”

HttpSession对象,但请注意“根对象

”是ValueStack接口的实现类OgnlValueStack。ValueStack接口是什么?值栈。也就是一组对象的堆栈。也就是说,在struts2中,根对象不是象,而是一组对象,是一个集合。通常的一个普通的POJO对可以push新的对象到值栈中,也可以pop弹出值栈的栈顶对象。假设user对象push到值见过的表达式一样,具有相同栈中,那么如下的表达式将与之前的结果:name

//

取用户的

,即age//取用户birthday//取用户生日//取用户所属客户的名称#request.parameters//取请求参数23Struts2与OGNL接前页也就是说,

使用name这个表达式的时候,ONGL会取“根对象”的name属性,但现在根对象是ValueStack,那么

ValueStack的name属性意味着什么呢?这意味着:ValueStack会先查看栈顶元素是否有name属性,如果有就返回该属性值,否则取出栈顶下的元素,继续查看,直到栈底为止。24临时小结ActionContext类的context对象就是Ognl的上下文对象,里面

了Application、Session、request、parameters、attr、ValueStack等对象。ValueStack就是Struts2框架设置的Ognl的根对象,里面中了一组数据,写Ognl表达式时框架会遍历ValueStack集合,查找第一个表达式匹配的对象使用。在Struts2框架中

ValueStack以外的Ognl对象时需要加#,如

session对象。25Struts2与OGNL重点是<s:debug/>Struts2框架向ValueStack中放入了哪些内容呢?可以通过Struts2的

<s:debug/>查看Ognl上下文中的内容。示例:编写一个Action类,返回到某个jsp页面视图。jsp页面代码如下:注意观察示例结果中哪些是需要通过#

的对象另外注意ValueStack中缺省的数据是从哪里来的呢?26Struts2与OGNLStruts2框架总是向ValueStack的栈顶放入Action实例。也就是示例:演示Ac);说g=

)rprivate

Strin@Overridepublic

StringcurrentTimereturn

SUCC}public

Stringretu}public

void

sthis.}27Struts2与OGNLActionContext类中的context是Ognl上下文对象的另一个示例:public

class

OgnlTest1

extends

ActionSupport

{o

world~!");@Overridepublic

String

execute()

throws

Exception

{ActionContext.getContext().put("shinowit",

"return

super.execute();}}<body><s:debug></s:debug><s:property

value="#shinowit"/></body><s:debug>输出28Struts2与OGNL台的JSP页面中使用呢?<s:property

value=“表达式”/>进行输OGNL中的值如何可以通过Struts2的出。OGNL中对应的数据值。其它的编辑控件也会自动的示例:定义。private@Overpublic}public

String

getName()关于return

name;}public

void

setName(Stringname){

=

name;}的使用不是本章的重点,以后单独详细讲29Struts2框架中OGNL的典型应用场景Struts2

中:<s:property

value=""

/><s:textfield

name=“"></s:textfield>Struts2的XML配置文件中:<result

type="redirect">/main.jsp?name=${name}</result>30与OGNL有关的Struts2配置参数在Struts2中可以通过定义xml配置参数决定是否允许OGNL调用类的静态方法,配置参数为:<constant

name="struts.ognl.allowStaticMethodAccess"value="true"></constant>OGNL中 静态方法有专门的语法<s:property

value="@com.shinowit.Demo@abc()">注意,两个@是约定..也就是必须这么写.第一个@后面跟的是类的全名.第二个@后面跟的是对应的方法名.当然,这个方法必须是静态的31注意在JSP2.1中#被用作了JSPEL(表达式语言)的特殊记好,所以对OGNL的使用可能导致问题。最简单的方法是禁用

JSP2.1的EL特性,需要手动修改web.xml文件增加以下配置参数:<jsp-config><jsp-property-group><url-pattern>*.jsp</url-pattern><el-ignored>true</el-ignored></jsp-property-group></jsp-config>32Struts2与OGNL小结Struts2将OGNL上下文设置为Struts2中的ActionContext类的context对象,并将值栈(ValueStack)作为OGNL的根对象。值栈通过一个ValueStack接口来定义,对应的实现类是OgnlValueStack。值栈特殊的特点是 还可以继续放任意多个对象,当计算表达式的值的时候,Struts2会从栈顶查找最匹配的对象使用。值栈中的第一个元素是Struts2的Action类。Struts2的 中可以书写OGNL表达式。在Struts2中应用OGNL技术需要注意相关的配置参数要设置正确。3334OGNL表达式的使用OGNL表达式可以支持以下操作:定义和使用常量。使用操作符#、$、%操作对象数据或作表达式求值。支持对象方法调用,如xxx.doSomeSpecial();支持类静态的方法调用和值

,表达式的格式为@[类全名(包括包路径)]@[方法名

|

值名],例如:@java.lang.String@format(‘foo

%s’,

‘bar’)或@tutorial.MyConstant@APP_NAME;操作集合对象。35定义和使用常量象的属性名,从而导字符串常量(string

literal)以单引号或双引号括起来的字符串,例如:‘ o

World’或” oWorld”.在JAVA中,不能用单引号来界定字符串常量,而在OGNL中是可以的。不过特别要注意的是:如果是单个字符的字符串常量,则必须使

引号来界定,例如:“S”,也就是说写了双引号的一定是字符串,单引号用在单字符的情况下就不是字符串了。OGNL的字符串也支持转义序列,例如:要在JSP页面中输出”Yousaid

,” o

World”.”,如下:<s:property

value="'You

said,\" o

World\".'"/>注意:不要忽略了用于界定

个常量字符串的单引号。如果没有写单引号,那么整个字符这个示例里面单引号才是字符串的开始作根对36定义和使用常量引号,否字符常量(Character

literal)以单引号括起来的字符。例如,‘H’。注意,不能使则将被看成是字符串常量。数值常量(Numeri

eral)除了Java中的int,long,float,double外,OGNL还让你用“B”或

“b”后缀指定BigDecimal常量,用“H”或”h”后缀指定BigInteger常量,例如,123(int常量),123l(long常量),123.35f(float常量),123b(BigDecimal常量),123h(BigInteger常量)。常量(Boolean

literal)true和falsenull常量(nullliteral)null值,如%{null}37OGNL操作符之“#”的用途OGNL上下文中的内容,在Struts2中,通过#可以到的有:parameters:包含当前HTTP请求参数的Map例如:#parameters.id作用相当于request.getParameter("id")示例<s:property

value="#parameters.id[0]"/>注意id参数提供了两个OGNL操作符之“#”的用途#request:取得包含当前HttpServletRequest的属性(attribute)的Map例如:#request.userName相当于request.getAttribute("userName")注意#request取得的是包含attribute的map,#parameters取得是才是请求参数。示例:<%

request.setAttribute("demo","shinowit");

%><s:property

value="#request.demo"/>OGNL操作符之“#”的用途session:包含当前HttpSession的属性(attribute)的Map例如:#session.userName相当于session.getAttribute("userName")示例:<%

session.setAttribute("demo","shinowit");

%><s:property

value="#session.demo"/>OGNL操作符之“#”的用途application:包含当前应用的ServletContext的属性(attribute)的Map例如:#application.userName相当于application.getAttribute("userName")示例:<%

application.setAttribute("demo","shinowit");

%><s:property

value="#application.demo"/>OGNL操作符之“#”的用途attr:用于按request>session>application顺序其属性(attribute),#attr.userName相当于按顺序在以userName属性,直到找到为上三个范围(scope)内止.示例:<%request.setAttribute("str","request

value");session.setAttribute("str","session

value");application.setAttribute("str","application

value");%><s:property

value="#attr.str"/>OGNL操作符之“#”的用途用于过滤和投影(projecting)集合如过滤提取出价格小于100的

:books.{?#this.price<100};构造Map#{'foo1':'bar1','foo2':'bar2'}。注意OGNL中还可以构造List,构造List时不需要用到#,直接写{“value”,”value”}就是构造list43OGNL操作符之“%”的用途“%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。示例代码:<h3>%的用途</h3><s:url

value="#abc"/><!--这个将会有输出内容#abc--><s:url

value="%{#abc}"/><!--这个将不会有输出内容-->#abc符合ognl表达式语法,但是在url

中当做字符串使用了,使用%{}以后会无条件将%{}内的内容按照ognl表达式处理。44OGNL操作符之“$”的用途$”有两个主要的用途:1.用于在

资源文件中,

OGNL表达式例如

资源文件中的代码:reg.agerange=资源信息:必须在${min}同${max}之间。OGNL表达式2.在Struts

2框架的配置文件中例如下面的代码片断所示:<validators><fieldname=”intb”><field-validator

type=”int”><param

name=”min”>10</param><param

name=”max”>100</param><message>Action-test校验:数字必须为${min}为${max}之间!</message></field-validator></field></validators>45OGNL操作符之“$”的用途接前页:Struts

2配置文件中使用$

OGNL表达式示例:<action

name=“AddPhoto”

class=“addPhoto”><interceptor-ref

name=“fileUploadStack”

/><resulttype=“redirect”>ListPhotos.action?albumId=${albumId}</result></action>46OGNL表达式可 的资源上下文中的各种资源,包括:OGNL表达式可以属性方法静态属性和方法构造方法数组集合–投影、选择(?^

$)Lambda

表达式

:[…]47OGNL

举例调用值栈(ValueStack)中的属性<s:property

value=“user.username”

/>调用Action中的静态方法<s:property

value=“@com.shinowit.LoginAction@get()”

/>调用JDK中的 静态方法<s:pro

需要先配置struts.ognl.allowStaticMethodAccess为true<s:property

value="@@max(1,2)"/>两种写法等价,没有明确指明时缺省调用java.lang.Math类的静态方法48OGNL

举例调用值栈中对象的普通方法<s:property

value="user.get()"/>调用普通类中的静态属性<s:property

value="@com.vo.Addrss@aa"/>//注意aa属性需要为public

权限的调用普通类的构造方法<s:property

value="new

com.shinowit.model.Student('','20')"/>获取List<s:property

value="testlist"/>获取List某一元素<s:property

value="testlist[0]"/>49OGNL

举例获取Set<s:property

value=“testset”

/>获取Map<s:property

value=“testmap”

/>获取Map中某一元素<s:property

value=“testmap[‘m1’]”

/>注意由于Set是无序的,所以不能使用下标获取数据。静态方法<constant

name="struts.ognl.allowStaticMethodAccess"

value="true"

/><s:property

value="@com.test.util.S@abc()">50OGNL与集合生成List语法语法为:{e1,e2,e3}示例<s:select

label="label"

name="name"

list="{'name1','name2','name3'}"value="%{'name2'}"/>上面的代码生成了一个HTML

Select对象,可选的内容为:name1,name2,name3,默认值为:name2。51OGNL与集合生成Map语法语法:#{key1:value1,key2:value2}示例<s:select

label="label"

name="name1"

list="#{'foo':'foovalue','bar':'barvalue'}"

value="'bar'"/>上面的代码生成了一个HTML

Select对象,foo名字表示的内容为:foovalue,bar名字表示的内容为:barvalue。52OGNL集合操作对于集合,OGNL提供了两个元素符:in和notin,其中in判断某个元素是否在指定集合中;not

in则用于判断某个元素是否不在指定集合中。示例:判断一个对象是否在List内。<s:if

test="'foo'

in

{'foo','bar'}">a</s:if><s:else>b</s:else><s:if

test="'foo'

not

in

{'foo','bar'}">c</s:if><s:else>d</s:else>如果表达式为true,输出a53OGNL集合操作取得一个List的一部分?–所有满足选择逻辑的对象^-

第一个满足选择逻辑的对象$-

最后一个满足选择逻辑的对象示例见后续ppt:54集合过滤示例?,^,$的使用-Student实体类public

class

Student

{private

String

id;privateString

name;private

intage;public

Student(){}public

Student(String

id,Stringname,int

age){this.id=id;=name;this.age=age;}…getter/setter方法省略…}55集合过滤示例?,^,$的使用-Action类public

class

OgnlTest2

extends

ActionSupport

{priva ist<Student>

stus;public

List<Student>

getStus()

{return

stus;}",20));",21));",22));@Overridepublic

String

execute()

throws

Exception

{stus=new

ArrayList<Student>();stus.add(newStudent("0001","stus.add(newStudent("0002","stus.add(new

Student("0003","return

SUCCESS;}}56集合过滤示例?,^,$的使用-前台jsp<s:iterator

var="validStudents"

value="stus.{?#this.age>20}"><s:property

value="id"/><s:property

value="name"/><s:property

value="age"/><br></s:iterator>?换成^、换成$试试57OGNL集合操作OGNL的集合操作如果想要创建指定的Map类型,可以在左花括号之前指定Map实现类的类名。如:#@java.util.LinkedHashMap@{“

”:“zhangsu”}Map元素通过key来

,两种语法:map[‘key’]形式:<s:property

value="#{'aaa':'zhangsan'}['aaa']"/>map.key形式:<s:property

value="#{'aaa':'zhangsan','bbb':'lishi'}.bbb"/>58OGNL集合操作在OGNL中创建数组与Java中创建数组是类似的。例如,表达式:new

int[]{1,2,3}//代表创建了一个int类型的数组,由1,2,3元素组成new

int[5]//代表创建了一个5个元素的数组,初始化值为0数组元素通过索引来 ,array[0],new

int[]{1,2,3}[1],同时在java中的数组具有属性

length,在OGNL中也可以直接 ,如:array.length。<s:property

value="new

int[]{1,2,3,4}.length"/>59OGNL集合操作Ognl表达式集合属性的写法:集合类型OGNL中特殊的集合伪属性伪属性

OGNL表达式JAVA代码List,Set,Map

size,isEmptylist.size,

set

isEmptylist.size(),

set

isEmpty()Setiteratorset.iteratorset.iterator()Iteratornext,hasNextit.next,it.hasNextit.next(),it.hasNext()<s:property

value="{}.size"/><!--空list,输出0-->L

<s:property

value="{}.isEmpty"/><!--空list,输出true-->M<s:property

value="{'aaa','bbb'}.isEmpty"/><!--两个空字符串list,输出false-->6061Struts2增强特性假设值栈中有两个对象:student和employee,两个对象都有name属性,student有学号属性number,而employee有薪水属性salary。employee先入栈,student

栈,位于栈顶,那么对于表达式name,

的就是student的name属性,因为student对象位于栈顶;表达式salary, 的就是employee的salary属性。正如你所见, 值栈中的对象属性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2在OGNL基础上做出的改进。62Struts2增强特性-[N]语

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论