struts2

更新时间:2024-06-03 22:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

.Struts2课件

1 Mvc与servlet

1.1 Servlet的优点

1、 是mvc的基础,其他的框架比如struts1,struts2,webwork都是从servlet

基础上发展过来的。所以掌握servlet是掌握mvc的关键。

2、 Servlet把最底层的api暴漏给程序员,使程序员更能清楚的了解mvc的各

个特点。

3、 程序员可以对servlet进行封装。Struts2就是从servlet中封装以后得到的

结果。

4、 市场上任何一个mvc的框架都是servlet发展过来的,所以要想学好struts2

这个框架,了解servlet的运行机制很关键。

1.2 Servlet的缺点

1、 每写一个servlet在web.xml中都要做相应的配置。如果有多很servlet,会

导致web.xml内容过于繁多。 2、 这样的结构不利于分组开发。

3、 在servlet中,doGet方法和doPost方法有HttpServletRequest和

HttpServletResponse参数。这两个参数与容器相关,如果想在servlet中作单元测试,则必须初始化这两个参数。

4、 如果一个servlet中有很多个方法,则必须采用传递参数的形式,分解到每

一个方法中。

2 重构servlet

针对servlet以上的特点,我们可以对servlet进行重构,使其开发起来更简单。更容易,更适合团队协作。

重构的目标:

1、 只写一个serlvet或者过滤器,我们这里选择过滤器。

2、 不用再写任何的servlet,这样在web.xml中写的代码就很少了。 3、 原来需要写serlvet,现在改写action。

4、 在action中把HttpServletRequest参数和HttpServletResponse参数传递

过去。

5、 在过滤器中通过java的反射机制调用action。 6、 详细过程参照cn.itcast.action包中的内容

3 Struts2介绍

1、 struts2是apache组织发明的开源框架。是struts的第二代产品。 2、 struts2是在struts和webwork基础上整合的全新的框架。 3、 struts2的配置文件组织更合理,是企业开发很好的选择。 4、 struts2的拦截器为mvc框架注入了全新的概念。

4 Struts2入门

4.1 新建一个工程为struts2 4.2 修改工程的编码为utf-8 4.3 导入jar包

在新建的工程下创建一个文件夹名为lib,把相应的jar包到入到lib文件夹中,并且放入到classpath中,jar包有: 4.4 创建test.jsp文件

4.5 创建HelloWorldAction

package cn.itcast.struts2.action; import com.opensymphony.xwork2.Action; public class HelloWorldAction implements Action{ public String execute() throws Exception { // TODO Auto-generated method stub System.out.println(\ return \ } }

4.6 编写success.jsp文件

This is my JSP page.
base命名空间下的HelloWorld运行完成! 4.7 编写struts配置文件

该文件放在src下即可 4.8 编写web.xml文件

4.9 运行结果

测试struts2,输出有命名空间的helloWorld
测试struts2,输出没有命名空间的helloWorld
4.10 加载struts.xml过程

说明:

1、 在web服务器启动的时候,执行的是过滤器中的init方法。在这里回顾

一个问题:一个过滤器中的init方法在什么时候执行?总共执行几次?

2、 在启动服务器的时候,执行了过滤器中的init方法,加载了三个配置文件

struts-default.xml、struts-plugin.xml、struts.xml

3、 因为这三个文件的dtd约束是一样的,所以如果这三个文件有相同的项,

后面覆盖前面的。因为先加载前面的,后加载后面的。 4、 struts.xml文件必须放在src下才能找到。

5 Struts2基本配置

5.1 Extends用法

说明:

1、 上述内容中,因为在struts.xml文件中,所有的包都继承了struts-default

包(在struts-defult.xml文件中),所以程序员开发的action具有struts-default包中所有类的功能。

2、 而struts-default.xml文件在web服务器启动的时候就加载了。 3、 在struts-default.xml文件中,定义了struts2容器的核心内容。

4、 可以做这样的尝试:把extends=”struts-default”改为extends=””会怎么

样呢?

5.1.1 例子

在struts.xml文件中

在上述的配置中,重新设置了一个包,名称为test,这个包继承了base。所以当访问http://localhost:8080/struts2/test/helloWorldAction.action时也能输出正确的结果,并且命名空间和base包中的命名空间没有任何关系了已经。

如果在struts2的配置文件中不写extens=”struts-default”会出现什么样的结构呢?

5.2 ActionSupprot

在struts框架中,准备了一个ActionSupport类 代码段一: public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable { 代码段二: /** * A default implementation that does nothing an returns \ *

ActionSupport是一个默认的Action实现,但是只返回了一个字符串success * Subclasses should override this method to provide their business logic. *

子类需要重新覆盖整个方法,在这个方法中写相应的逻辑 * See also {@link com.opensymphony.xwork2.Action#execute()}. * * @return returns {@link #SUCCESS} * @throws Exception can be thrown by subclasses. */ public String execute() throws Exception {

说明:

1、 2、 3、

代码段一说明了ActionSupport也实现了Action接口(以前写的类实现了Action接口)

代码段二说明如果程序员写自己的action继承了ActionSupport,需要重新覆盖execute方法即可。 这个方法默认的返回的是success;

在配置文件中,还可以这么写: 可以看到action标签中没有class属性,在struts-default.xml中,

在struts.xml中可以按照如下的形式引入别的struts的配置文件

5.4 命名空间

在说明

extends

用法的时候,我们引用了这样一个

url:http://localhost:8080/struts2/base/helloWorld.action。如果我们把url改成这样:

http://localhost:8080/struts2/base/a/helloWorld.action。行吗?答案是可以的。再改成这样的url:http://localhost:8080/struts2/base/a/b/helloWorld.action ,行吗?答案也是可以的。如果这样呢http://localhost:8080/struts2/helloWorld.action可以吗?这样就不行了。为什么? 步骤:

1、 struts2会在当前的命名空间下查找相应的action

2、 如果找不到,则会在上级目录中查找,一直查找到根目录 3、 如果根目录也找不到,报错。

4、 如果直接访问的就是根目录,找不到,这样的情况就会直接报错。

不会再去子目录中进行查找。

6 结果类型

6.1 说明

1、 每个action方法都返回一个String类型的值,struts一次请求返回什么值是由这

个值确定的。

2、 在配置文件中,每一个action元素的配置都必须有result元素,每一个result

对应一个action的返回值。 3、 Result有两个属性:

name:结果的名字,和action中的返回值一样,默认值为success; type:响应结果类型,默认值为dispatcher.

6.2 类型列表

在struts-default.xml文件中,如下面所示:

说明:

1、 从上述可以看出总共10种类型

2、 默认类型为ServletDispatcherResult即转发。 3、 结果类型可以是这10种结果类型的任意一种。

6.2.1 Dispatcher类型

6.2.1.1 说明

Dispatcher类型是最常用的结果类型,也是struts框架默认的结果类型。

6.2.1.2 例子

页面参照:resulttype/testDispatcher.jsp

Action参照:DispatcherAction 配置文件:struts-resulttype.xml

在配置文件中,可以有两种写法: 第一种写法:

下面的图说明了location的来历:

6.2.2 Redirect类型

6.2.2.1 说明

Redirect属于重定向。如果用redirect类型,则在reuqest作用域的值不能传递到前

台。

6.2.2.2 例子

页面:resulttype/testRedirect.jsp Action:RedirectAction

配置文件:struts-resulttype.xml

6.2.3 redirectAction类型

6.2.3.1 说明

1、 把结果类型重新定向到action 2、 可以接受两种参数

a) actionName: action的名字 b) namespace:命名空间

6.2.3.2 例子

第一种方式:

7 Action原型模式

7.1 回顾servlet

在servlet中,一个servlet只有一个对象,也就是说servlet是单例模式。如果把一个集合写在servlet属性中,则要考虑线程安全的问题。

7.2 Action多例模式

但是在struts2的框架中,并不存在这种情况,也就是说struts2中的action,只要访问一次就要实例化一个对象。这样不会存在数据共享的问题。这也是struts2框架的一个好处。

7.3 实验

可以写一个类,如下: package cn.itcast.struts2.action.moreinstance; import com.opensymphony.xwork2.ActionSupport; @SuppressWarnings(\ public class MoreInstanceAction extends ActionSupport{ public MoreInstanceAction(){ System.out.println(\配置文件为: } public String execute(){ System.out.println(\ return SUCCESS; } } 径,如果构造函数中的”create new action”输出两次,说明创建了两次对象。 8 通配符

8.1 Execute方法的弊端

假设有这样的需求:

1、 有一个action为PersonAction。

2、 在PersonAction中要实现增、删、改、查四个方法。 3、 但是在action中方法的入口只有一个execute方法

4、 所以要想完成这样的功能,有一种方法就是在url链接中加参数。

那么在action中的代码可能是这样的:

PatternAction public class PatternAction extends ActionSupport{ private String method; public String execute(){ if(method.equals(\ //增加操作 }else if(method.equals(\ //修改操作 }else if(method.equals(\ //删除操作 }else{ //查询操作 } return \ } }

可以看出这样写结构并不是很好。而通配符的出现解决了这个问题。

8.2 method属性

Pattern.jsp 访问PersonAction的add方法:

Struts-pattern.xml PatternAction public String add(){ return \} 说明:从上述代码可以看出只要配置文件中的method属性的值和方法名称一样就可以了。但是这种写法有弊端。如果aciton中需要5个方法。则在struts的配置文件中需要写5个配置,这样会导致配置文件的篇幅很大。而且重复性也很大

8.3 动态调用方法

在url中通过action名称!方法名称可以动态调用方法。 Pattern.jsp 动态调用PatternAction中的add方法:
struts-pattern.xml 说明:这样的情况在配置文件中不需要method属性

8.4 通配符映射 8.4.1 映射一

需求:a_add.action、b_add.action、c_add.action全部请求PatternAction的add方法 Pattern.jsp 通配符映射实例1:
说明:不管是a_add还是b_add还是c_add的路径都指向PatternAction的add方法。 struts-pattern.xml 上述结构是很差的,经过改进如下:

请求PersonAction和StudentAction的add方法 Pattern.jsp 通配符映射实例2:
请求studentAction的add方法 Struts-pattern.xml name=\ 说明:*和{1}是相对应的关系。

method=\method=\class=” 8.4.3 映射三

需求:在TeacherAction中有增、删、改、查的方法。这个时候配置文件怎么写比较简单? Pattern.jsp 通配符映射实例3: struts-pattern.xml 说明:*和method的属性值保持一致。 延伸: 第一个*匹配{1},第二个*匹配{2} 9 全局结果类型

9.1 说明

当很多提交请求跳转到相同的页面,这个时候,这个页面就可以成为全局的页面。在struts2中提供了全局页面的配置方法。

9.2 例子

Struts-pattern.xml 注意: * 这个配置必须写在action配置的上面。dtd约束的规定。 * 如果在action的result中的name属性也有success值,顺序为 先局部后全局。

9.3 错误的统一处理 9.3.1 xml文件

9.3.2 Java文件

10 Struts2与serlvet接口

10.1 说明

通过前面的练习大家都知道,在action的方法中与servlet的所有的API是没有任何关系的。所以在struts2中做到了aciton与serlvet的松耦合,这点是非常强大的。但是如果没有HttpServletRequest,HttpServletSession,ServletContext有些功能是没有办法完成的。比如购物车程序,需要把购买的物品放入session中。所以就得找一些路径使得在struts2中和serlvet的API相结合。

10.2 实现一

Struts2中提供了ServletActionContext类访问servlet的api。 Servlet.jsp 通过SerlvetActionContext类访问servlet的API:
ServletAction

10.3 实现二 ServletAction public class ServletAction extends ActionSupport implements ServletContextAware, SessionAware,ServletRequestAware{ private HttpServletRequest request; private Map sessionMap; private ServletContext servletContext; public String testServletAPI2(){ System.out.println(this.servletContext); System.out.println(this.sessionMap); System.out.println(this.request); return \ } public void setServletContext(ServletContext context) { // TODO Auto-generated method stub this.servletContext = context; } public void setSession(Map session) { // TODO Auto-generated method stub this.sessionMap = session; } public void setServletRequest(HttpServletRequest request) { // TODO Auto-generated method stub this.request = request; } }

11 拦截器

假设有一种场景:

在action的一个方法中,要进行权限的控制。如果是admin用户登入,就执行该方法,如果不是admin用户登入,就不能执行该方法。

11.1 实现方案一

AccessAction public String testAccess(){ if(this.username.equals(\ //执行业务逻辑方法 return SUCCESS; }else{ //不执行 return \ } } 说明:

5、 这样做,程序的结构不是很好。原因是权限的判断和业务逻辑的

方法紧密耦合在了一起。如果权限的判断很复杂或者是业务逻辑很复杂会造成后期维护的非常困难。所以结构不是很好

6、 这种形式只能控制一个action中的一个方法。如果很多action中

的很多方法都需要这种控制。会导致大量的重复代码的编写。

11.2 实现方案二

动态代理可以实现。请参见cn.itcast.struts.jdkproxy包下的类。

11.3 实现方案三

在struts2中,用拦截器(interceptor)完美的实现了这一需求。在struts2中, 内置了很多拦截器,在struts-default.xml文件中可以看出。用户还可以自定义

自己的拦截器。自定义拦截器需要以下几点: 1、 在配置文件中: 包括两个部分:声明拦截器栈和使用拦截器栈

struts-interceptor.xml

public class PrivilegeInterceptor implements Interceptor{ public void destroy() { // TODO Auto-generated method stub } public void init() { // TODO Auto-generated method stub } public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println(\ //得到当前正在访问的action System.out.println(invocation.getAction().toString()); //得到Ognl值栈 System.out.println(invocation.getInvocationContext().getValueStack()); //请求路径action的名称,包括方法 System.out.println(invocation.getProxy().getActionName()); //方法名称 System.out.println(invocation.getProxy().getMethod()); //命名空间 System.out.println(invocation.getProxy().getNamespace()); String method = invocation.invoke(); return null; } } 说明: 1、 这个类中intercept和destroy三个方法说明了一个拦截器的生命周期。 init、 2、 在interceptor方法中的参数invocation是执行action的上下文,可以从 这里得到正在访问的action、Ognl值栈、请求路径、方法名称、命名空间 等信息。以帮助程序员在拦截器中做相应的处理工作。 3、 红色部分是关键部分,就是调用action的方法。这里可以成为目标类的

11.4 Exception拦截器

12 验证

12.1 需求

验证用户名不能为空,密码也不能为空,并且长度不能小于6位数。

12.2 基本验证

ValidateAction.java public class ValidateAction extends ActionSupport{ private String username; private String password; //set和get方法 public String testValidate(){ return \ } public String aaa(){ return \ } public void validate() { if(this.username.equals(\ this.addFieldError(\用户名不能为空\ } if(this.password.equals(\ this.addFieldError(\密码不能为空\ }else if(this.password.length()<6){ this.addFieldError(\密码不能小于6个字符\ } } } 说明: ? 在ActionSupport类中有这样的描述: /** * A default implementation that validates nothing. * Subclasses should override this method to provide validations. */ public void validate() { } 这是一个默认的实现,子类应该覆盖整个方法去完成验证逻辑。 所以我们只需要去重写validate这个方法就可以了。 ? 从下面的图中可以看出错误信息的封装机制。 总的结构为Map> String为要验证的字段 List 封装错误信息 ? 错误信息会出现在input指向的页面。 ? validate是针对action中所有的方法进行验证。如果想针对某一个方法进行验证, 应该把validate方法改为validate方法名称(方法名称的第一个字母大写)。 12.3 框架验证

13 国际化

13.1 说明

一个系统的国际化就是根据操作系统的语言,页面上的表现形式发生相应的变化。比如如果操作系统是英文,页面的文字应该用英语,如果操作系统是中文,页面的语言应该是中文。

13.2 步骤 13.2.1 建立资源文件

资源文件的命名规则: 默认的命名为: 文件名前缀.properties 根据语言的命名为: 文件名前缀.语言种类.properties 例如: 中文: resource_zh_CN.properties 内容: item.username=用户名 item.password=密码 英文: resource_en_US.properties 内容: item.username=username_en item.password=password_en 默认: resource.properties 内容: item.username=username item.password=password

13.2.2 配置文件中

需要在配置文件中加入:

value=\ 说明:

1、 这样struts2就会去找你写的资源文件

2、 name的值可以在org/apache/struts2/default.properties中找到。 3、 如果放置的资源文件在src下,则value的值可以直接写,如果在

包中则可以写成包名.resource。

name=\

4、 在这里resource是个基名,也就是说可以加载以resource开头的文件。

13.2.3 页面中

利用就可以把资源文件中的内容输出来。

I18n/login.jsp 说明: 1、 标红色部分的是要从资源文件中找的内容。item.username和 item.password代码key的值。 2、 也可以利用%{getText('item.username')}方式来获取资源。采取的是 OGNL表达式的方式。 3、 getText的来源: 从源代码可以看出ActionSupport实现了TextProvider接口。 Provides access to {@link ResourceBundle}s and their underlying text messages.意思是说提供了访问资源文件的入口。而 TextProvider中提供了getText方法,根据key可以得到value。

13.2.4 在action中

可以利用ActionSupport中的getText()方法获取资源文件的value值。 I18n/LoginAction public class LoginAction extends ActionSupport{ public String login(){ String username = this.getText(\ System.out.println(username); String password = this.getText(\ System.out.println(password); return \ } } 说明:通过this.getText()方法可以获取资源文件的值。

14 OGNL

14.1 介绍

OGNL表达式是(Object-Graph Navigation Language)是对象图形化导航语言。OGNL是一个开源的项目,struts2中默认使用OGNL表达式语言来显示数据。与serlvet中的el表达式的作用是一样的。OGNL表达式有下面以下特点:

1、 支持对象方法调用,例如:objName.methodName(); 2、 支持类静态的方法调用和值访问,表达式的格式为

@[类全名(包括包路经)] @[方法名 | 值名] 例如:

@java.lang.String@format('foo%s','bar') @tutorial.MyConstant@APP_NAME;

3、 支持赋值操作和表达式串联,例如:

price=100, discount=0.8, calculatePrice(),这个表达式会返回80;

4、 访问OGNL上下文(OGNL context)和ActionContext

5、 操作集合对象

14.2 回顾el表达式

在servlet中学习的el表达式实际上有两步操作:

1、 把需要表现出来的数据放入到相应的作用域中

(req,res,session,application)。

2、 利用el表达式把作用域的值表现在页面上

14.3 ognl类图

14.4 ValueStack 14.4.1 说明

1、 ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用

实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。

2、 ValueStack贯穿整个action的生命周期。每一个action实例都拥有一

个ValueStack对象。其中保存了当前action对象和其他相关对象。 3、 Struts2把ValueStack对象保存中名为struts.valueStack的request域中。

14.4.2 ValueStack内存图

14.4.3 ValueStack的组织结构

从图上可以看出OgnlValueStack和我们有关的内容有两部分:即OgnlContext和CompoundRoot。所以把这两部分搞清楚很重要。

14.4.4 OgnlContext组织结构

14.4.4.1 _values

从上述可以看出,OgnlContext实际上有一部分功能是Map。所以可以看出_values就是一个Map属性。而运行一下下面的代码就可以看到: //在request域中设置一个参数 ServletActionContext.getRequest().setAttribute(\name\//在request域中设置一个参数 ServletActionContext.getRequest().setAttribute(\//在session域中设置一个参数 ActionContext.getContext().getSession().put(\\//在session域中设置一个参数 ActionContext.getContext().getSession().put(\\//获取OGNL值栈 ValueStack valueStack = ActionContext.getContext().getValueStack();

在_values的map中: key application request action com.opensymphony.xwork2.ActionContext.session value ApplicationMap RequestMap 自己写的action SessionMap

而request中的值为: { req_psw=req_psw, req_username=req_username, __cleanup_recursion_counter=1, struts.valueStack=com.opensymphony.xwork2.ognl.OgnlValueStack@3d58b2, struts.actionMapping=org.apache.struts2.dispatcher.mapper.ActionMapping@1f713ed }

可以看出在程序中存放在request作用域的值被放入到了_values的request域中。

com.opensymphony.xwork2.ActionContext.session的值为:

{session_username=session_username, session_psw=session_psw} 从上图中可以看出在程序中被加入到session的值在_values中也体现出来。

14.4.4.2 _root

从图中可以看出_root实际上CompoundRoot类,从类的组织结构图中可以看出,这个类实际上是继承了ArrayList类,也就是说这个类具有集合的功能。而且在默认情况下,集合类的第一个为ValueStackAction,也就是我们自己写的action。

14.5 总图

说明:

1、 上图是ognl完整的数据结构图,可以清晰得看出数据的组成。 2、 Context中的_root和ValueStack中的root(对象栈)里的数据结构和值是

一样的。

3、 这就意味着我们只需要操作OgnlContext就可以完成对数据的存和取

的操作。

4、 ValueStack内部有两个逻辑的组成部分:

a) ObjectStack

Struts会把动作和相关的对象压入到ObjectStack中。

b) ContextMap

Struts会把一些映射关系压入到ContextMap中

14.6 存数据 14.6.1 Map中存数据

14.6.1.1 方法1

//向map中存放数据 ServletActionContext.getRequest().setAttribute(\ServletActionContext.getRequest().setAttribute(\ActionContext.getContext().getSession().put(\ActionContext.getContext().getSession().put(\上面的代码都是往ContextMap中存放数据。因为这些值都是具有映射关系的。

14.6.1.2 方法2

ActionContext.getContext().put(\

通过执行上述代码把”msg”和”msg_object”放入到了ContextMap中。

14.6.2 值栈中存数据

14.6.2.1 方法1

/* * 把对象放入到值栈中 */ //方法一:先得到root,把一个对象压入到root中 ValueStack valueStack = ActionContext.getContext().getValueStack(); valueStack.getRoot().add(new Person()); valueStack.getRoot().add(new Student()); 运行以后的值栈结构图:

从内存图中可以看出最后被压入的到list中对象在最下面。

图为ArrayList中的add方法的解释: 追加的指定的元素放到集合的最下面。

14.6.2.2 方法2

/* * 方法二:先得到root,利用add(index,Object)把一个对象压入到root中 * 这里index指的是集合中的位置 */ ValueStack valueStack = ActionContext.getContext().getValueStack(); valueStack.getRoot().add(new Person()); valueStack.getRoot().add(0, new Student());

运行后的结构图为:

从图中可以很明显看出新创建的Student对象被放到了第一个位置,因为 Index的值为0,所以是第一个位置。

14.6.2.3 方法3

把一个键值对存放在对象栈中,做法为: /* * 方法三: * 把一个键值对存放在对象栈中 */ ValueStack valueStack = ActionContext.getContext().getValueStack(); valueStack.set(\ 对象栈图为:

从图中可以看出上面的代码执行过程为:

1、 先把”msg”和”msg_object”两个字符串封装成Map 2、 再把封装以后的Map放入到对象栈中。

14.6.2.4 方法4

/* * 方法4 * 利用ValueStack的push方法可以把一个对象直接压入对象栈的第一个位置 */ ValueStack valueStack = ActionContext.getContext().getValueStack(); valueStack.push(new Person());

执行完push方法以后,对象栈的情况如下:

Push方法把新创建的Person对象放入到了对象栈的首个位置。

14.7 OGNL Context

14.7.1 说明

1、 上图为OGNL Context的结构图

2、 当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后

把action压入到值栈中。所以action的实例变量可以被ognl访问。所以利用ognl表达式可以访问action。

14.8 ActionContext

/* * ActionContext的作用 */ ActionContext.getContext().getSession().put(\ActionContext.getContext().getSession().put(\ValueStack valueStack = ActionContext.getContext().getValueStack(); 14.8.1 说明

从上面的代码中可以看出来,struts2中的ActionContext的作用是提供了对ognl数 据的操作。并且可以通过ActionContext获取到经过struts2封装了的session等参数。

14.9 ServletActionContext

/* * 返回servlet中的request和servletcontext */ ServletActionContext.getRequest().setAttribute(\ServletActionContext.getRequest().setAttribute(\ServletActionContext.getServletContext(); //得到ActionContext ServletActionContext.getContext(); 14.9.1 说明

1、 可以通过ServletActionContext得到servlet中的一些类,比如

HttpServletRequest,ServletContext等

2、 可以通过ServletActionContext返回ActionContext

14.10 Ognl表达式 14.10.1 简述

从9.6到9.9讨论了ognl的结构、如何存数据。9.10重点讨论如何把ognl结构中的数据呈现在页面上。所以Ognl表达式的作用就是把OgnlContext中的数据输出到页面上。

14.10.2 el表达式例子

参照课堂演示例子

14.10.3 ognl表达式例子

14.10.3.1 用法1(#号用法)

说明:

1、 访问OGNL上下文和action上下文,#相当于ActionContext.getContext(); 2、 如果访问的是map中的值而不是对象栈中的值,由于map中的数据不是

根对象,所以在访问时需要添加#前缀。 名称 parameters request 作用 包含当前HTTP请求的Map 包含当前HttpServletRequest属性的Map 包含当前HttpSession属性的Map 包含当前ServletContext属性的Map 用于按照request>session>application顺序访问其属性

注:也可以写为#request[?username?] #sesssion[?username?] #application[?username?]

例子 #parameters.id[0]=request.getParameter(“id”) #request.username=request.getAttribute(“username”); #session.username=session.getAttribute(“username”); #application.username=application.getAttribute(“username”); #attr.username相当于按照顺序在以上三个范围内读取username的属性,直到找到为止。 session application attr

主要步骤: 在action中

public String testScope() { // 把字符串\放入到request域中 ServletActionContext.getRequest().setAttribute(\ \ // 把字符串\放入到session域中 ServletActionContext.getRequest().getSession().setAttribute( \ // 把字符串\放入到application域中 ServletActionContext.getServletContext().setAttribute( \ return \ }

在页面中:

<%@ page language=\<%@ taglib uri=\ //导入struts2的标签 ognl表达式关于scope(request,session,application)的输出
request:

14.10.3.2 用法2

OGNL会设定一个对象(root对象),在struts2中根对象就是CompoundRoot,或者为OgnlValueStack中的root,通常被叫做ValueStack(值栈或者对象栈),如果要访问根对象的属性,则可以省略去#,直接访问对象的属性即可。 在action中

public String testObjectValue(){

//得到ognl的上下文

ValueStack valueStack =

ActionContext.getContext().getValueStack();

valueStack.set(\

return \

}

本文来源:https://www.bwwdw.com/article/9q16.html

Top