Struts2入门教程(全新完整版) 联系客服

发布时间 : 星期五 文章Struts2入门教程(全新完整版)更新完毕开始阅读1fd042cc376baf1ffd4fad14

N语法[1].top:
N语法top:

N语法取值:
N语法取值:

说明:规定栈顶的对象为[0],而我们只使用[0]的意思是从值栈中第一个对象取,一直取至栈底。N的意思是从值栈中的第N个对象开始,取到栈底为止。如果要想访问某个对象,需要使用[N].top,它的意思是取出符合N语法的栈顶对象,比如在这里,[0]会取出两个对象,而[0].top是取出这两个对象的栈顶对象。纯top可以简洁地取出值栈中的栈顶对象。

为什么要提出N语法,当我们通过chain链访问时,值栈中可能有两个以上的Action对象,如果这些对象中存在相同的属性,N便能正确区分他们。通常,这些Action对象的入栈顺序是:先访问先入栈。 从上面的N语法取值实例中,我们知道[N]top语法的一个重要作用就是能通过它们引用值栈对象中的属性。结合前面的五种[N]top语法实例,不难理解这里的取值实例。

补充:在此实例中,我们用调试会发现,值栈中还有一个DefaultTextProvider对象(因为此Action继承自ActionSupport),它的作用是获取资源文件中的内容(其实本质是ActionSupport重写了getText()方法),这也就是在国际化问题中我们能直接调用它的getText()方法的原因。 10.获取Stack Context中的信息

我们知道,除了可以从值栈中获取信息,还可以从Stack Context中获取信息,只是要加上#,下面我们通过scope对象来演示。首先是在LoginAction中增加如下字段:

Map myRequest; Map mySession;

随后再用前面提到的“在Action中获取Scope对象”的方式二来完成这些对象的初始化。即实现RequestAware和SessionAware接口。然后再在execute方法中增加如下内容:

myRequest.put(\, \属性\); mySession.put(\, \属性\);

最后在loginSuc.jsp中增加如下代码:

获取Request属性:
获取Session属性:
获取parameters属性:

说明:我们获取这些对象都用了#,因为这些对象都是存在一般的Context Map中,而不是存在值栈中。别最后一个信息的获取是因为我们在login.jsp中增加了如下代码:

关于这些scope的更多信息可以参看下表: 名称 parameters 作用 例子 #parameters.id[0]作用相当于包含当前HTTP请求参数的Map request.getParameter(\包含当前HttpServletRequest#request.userName相当于request.getAttribute(\的属性(attribute)的Map 包含当前HttpSession的属性(attribute)的Map #session.userName相当于session.getAttribute(\request session application Attr 包含当前应用的ServletContext#application.userName相当于的属性(attribute)的Map application.getAttribute(\用于按request > session > #application.userName相当于application顺序访问其属性 application.getAttribute(\11.总结$ # %的区别 $用于i18n和struts配置文件 #取得ActionContext的值

29

%将原来的文本串解析为ognl,对于本来就是ognl的文本不起作用。形式:%{要解析的文本串} 12.总结OGNL[重点]

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2使用OGNL作为默认的表达式语言。

相对于EL表达式,它提供了平时我们需要的一些功能,如:支持对象方法调用,支持各类静态方法调用和值访问,支持操作集合对象。OGNL有一个上下文的概念,这个上下文件实质就是一个Map结构,它实现了java.utils.Map接口,在struts2中上下文的实现为ActionContext,下面是上下文的结构示意图:

ValueStack(值栈,它是根对象) OgnlValueStack对象的[List] root变量 Parameters OGNL Context request session application attr 当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以接受OGNL访问。

访问上下文中的对象需要使用#号标注命名空间,如#application、#session。另外OGNL会设定一个根对象,在struts2中根对象就是ValueStack值栈对象,如果要访问根对象中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。在struts2中,根对象的实现类为OgnlValueStack,该对象不是我们想象的只存放单个值,而是存放一组对象,在OgnlValueStack类里有一个List类型的变量,就是使用这个List变量来存放一组对象。在root变量(List类型)中处于第一位的对象叫栈顶对象,通常我们在Ognl表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下寻找。 注意:struts2中 ,OGNL表达式需要配合struts的标签才可以使用。

五、拦截器

在前面我们已经初步使用过拦截器,下面继续细细探讨。 1.概述strust2中的拦截器

拦截器是Struts2框架的核心,它主要完成解析请求参数、将请求参数赋值给Action属性、执行数据校验、文件上传等工作。Struts2设计的灵巧性,拦截器起了关键性的作用,当需要扩展Struts2功能时,只需要提供对应拦截器,并将它配置在Struts2容器中即可;如果不需要该功能时,也只需要取消该拦截器的配置即可。

Struts2内建了大量的拦截器,这些拦截器以name-class对的形式配置在struts-default. xml文件中,其中name是拦截器的名字,就是以后我们使用该拦截器的唯一标识;class则指定了该拦截器的实现类,如果我们定义的package继承了Struts2的默认struts-default包,则可以自由使用它下面定义的拦截器,否则必须自己定义这些拦截器。 2.自定义拦截器

自定义拦截器需要特别注意的是不要忘记引入struts2默认的拦截器。为了实现某些操作,我们可以自定义拦截器,自定义拦截器有三种方式定义。分别为实现Interceptor接口,继承抽象类AbstractInterceptor,继承MethodFilterInteceptor类。 方式一,实现Interceptor接口。

30

准备工作,新建struts2interceptor项目。构建一个登录环境:当我们点登录链接时,便成功登录(为了方便,这里不进行验证)。即在link.jsp页面中写如下链接:

href=\<%=request.getContextPath()%>/login.action\>登录 然后,我们点击此链接便可以登录。login.action在strutst.xml中的的配置如下:

/success.jsp

com.asm.LoginAction为了简单,com.asm.LoginAction总是返回SUCCESS;这样请求这个Action总会返回到.../success.jsp页面。

编写拦截器:MyInterceptor类,内容如下:

package com.asm;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor; public class MyInterceptor implements Interceptor { }

public void destroy() { }

public void init() { }

public String intercept(ActionInvocation invocation) throws Exception { }

System.out.println(\开始拦截\);

String result = invocation.invoke(); System.out.println(\结束拦截\); return result;

为了使用此拦截器,我们必须将此拦截器进行注册,随后再在要使用此拦截器的Action中引用。即首先在中注册,内容如下:

注册完成后,如果我们要在login.action中使用此拦截器,只需要在中增加如下内容:

这样便成功为LoginAction配置了我们自定义的拦截器MyInterceptor,下面只需发布测试。

实例流程分析:当我们为LoginAction配置了拦截器时,并且有客户端请求此Action时,会首先被此拦截器拦住,然后执行System.out.println(\开始拦截\),随后我们调用invocation.invoke()方法,它会把请求继续传递给下一个拦截器,下一个拦截器也会继续执行相应代码后再调用invoke方法继续传递,直到请求到达最后一个拦截器,它会把请求传递给Action,比如,我们这里只用到了一个拦截器,当它执行完成后,会把请求直接转交到LoginAction处理,LoginAction处理完成后,它会返回结果给MyInterceptor拦截器。

方式二、继承AbstractInterceptor抽象类

创建拦截器类MyAbstractInterceptor:主要代码如下:

package com.asm;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyAbstractInterceptor extends AbstractInterceptor {

31

}

public String intercept(ActionInvocation invocation) throws Exception { }

System.out.println(\开始拦截\);

String result = invocation.invoke(); System.out.println(\结束拦截\); return result;

然后注册此拦截器,在元素进行进行配置,内容如下:

随后再在LoginAction中引用此拦截器,即在配置如下内容: 最后发布测试。

方式三、继承MethodFilterInteceptor类

创建拦截器类MyMethodFilterInterceptor,主要代码如下:

package com.asm;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; public class MyMethodFilterInterceptor extends MethodFilterInterceptor{ }

protected String doIntercept(ActionInvocation invocation) throws Exception { }

System.out.println(\开始拦截\); String result=invocation.invoke(); System.out.println(\结束拦截\); return result;

然后注册此拦截器,在元素进行进行配置,内容如下:

随后再在LoginAction中引用此拦截器,即在配置如下内容:

最后发布测试。

分析:当配置到此,实质便为LoginAction配置了三个拦截器,当我们点击登录时会在控制台打印出如下语句:

开始拦截 Abs开始拦截 method开始拦截

--先执行拦截器,再执行此Action method结束拦截 Abs结束拦截 结束拦截

其实当我们点击登录时,本来是要访问LoginAction,最后会把LoginAction的执行结果传递给访问者。但是当我们配置了拦截器时,当我们去访问Action时,会首先被拦截,随后拦截器执行一些操作后才会继续把请求传递下去。下面作图说明拦截流程:

32