Struts 2 Web开发学习实录--总结

来源:互联网 发布:淘宝买家后台操作流程 编辑:程序博客网 时间:2024/05/16 09:42

第一章

1   Struts 2简介 

Struts 2控制器可以分为核心控制器与业务控制器。Struts 2的核心控制器是FilterDispatcher,业务控制器是Action。其中,核心控制器在Web应用中负责拦截所有的用户请求。

Struts 2框架提供了强大的标签库,通过这些标签库,可以大大减小JSP页面的代码编写。而且,Struts 2的标签库并不只是提供了表现层数据处理,还提供了基本的流程控制等功能,例如:输出表单数据校验信息。

 

 

 

2   Struts 2的框架体系

 

(1)核心控制器(FilterDispatcher)

是Struts 2框架的基础,它包含了框架内部的控制流程和处理机制。在Web应用中作为一个Filter运行,负责拦截所有的用户请求。如果用户请求以.action结尾,则该请求被转入Struts 2框架处理。

 

(2)业务控制器(Action)

就是用户实现Action的实例。Action一般都有一个execute()方法,该方法返回一个字符串,这个字符串是一个逻辑视图名,通过配置后对应一个视图。

 

 

 

3   安装Struts 2

只需将Struts 2框架目录中的lib文件夹下几个JAR文件,复制到Web应用中WEB-INF/lib目录即可。这几个JAR文件如下:

struts2-core-x.x.x.jar  :Struts 2的核心库

xwork-x.x.x.jar  :WebWork的核心库

ognl-x.x.x.jar  :OGNL表达式语言,Struts 2支持该EL。

freemarker-x.x.x.jar  :表现层框架,定义Struts 2的可视组件主题。

commons-logging-x.x.x.jar  :日志管理

 

 

 

4    Struts本质

Struts只是一个MVC框架,用于快速开发Java Web应用。Struts实现的重点是C(Controller),包括ActionServlet/RequestProcessor和定制的Action,也有为视图提供的一系列定制标签(Custom Tag),但Struts几乎没有涉及M(Model)。

Struts的目的是为了减少在运用MVC设计模式来开发Web应用的时间。核心是WebWork。

 

 

 

5    Struts2和Struts1的区别

(1)Action类

Ø Struts1要求Action类继承一个抽象基类。

Ø Struts2的Action类可以实现Action接口,也可以实现其他接口。Struts2提供一个ActionSupport基类去实现其他接口。      

 

 

(2)线程模式

Ø Struts1 Action是单例模式并且必须是线程安全的,因为仅有一个Action实例来处理所有的请求。

Ø Struts2 Action对象为每个请求产生一个实例,因此没有线程安全问题。实际上,Servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题。

 

 

(3)Servlet依赖

Ø Struts1 Action依赖于Servlet API,因为当一个Action被调用时,HttpServletRequest和HttpServletResponse被传递给execute()方法。

Ø Struts2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。

 

(4)可测性

Ø 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API。

Ø Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持使测试更加容易。

 

(5)表达式语言

Ø Struts1整合了JSTL,因此使用JSTL EL。

Struts2可以使用JSTL,它更支持一个更强大和灵活的表达式语言-Object-GraphNavigation Language(OGNL对象图导航语言)

Ø Struts1使用标准JSP机制把对象绑定到页面来访问。

Struts2使用ValueStack技术,使taglib能够访问值而不需要把页面(view)和对象绑定起来。

 

(6)类型转换

Ø Struts1 ActionForm属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每个实例来说是不可配置的。

Ø Struts2使用OGNL进行类型转换,由OGNL提供基本和常用对象的转换器。

 

(7)校验

Struts1支持在ActionForm的validate()方法中手动校验,或者通过Commons Validator的扩展来校验。

Struts2支持通过validate()方法和XWork校验框架来进行校验。

 

(8)Action执行的控制

Ø Struts1支持每一个模块,有单独的Request Processor(生命周期),但是模块中的所有Action必须共享相同的生命周期。

Ø Struts2支持通过拦截器堆栈(Interceptor Stacks)为每个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。

 

 

 

 

6   Struts2的配置文件

共有5类配置文件,分别为:

Ø struts.xml:主要是对对应程序作相应配置(包括对每个动作进行相应拦截器的调用,对每个动作的运行结果进行配置)

 

Ø struts_default.xml:注册默认的结果类型和拦截器,用于定义框架自身使用的action映射和result定义,是struts2框架的默认加载的配置文件(默认的配置文件包在Struts2-core-VERSION.jar中),定义struts2的一些核心bean和拦截器。

 

Ø struts.properties:定义框架自身的全局变量,该文件定义的全局属性也可以在struts.xml中定义。

 

Ø web.xml:不属于Struts2框架特有的文件,而是所有Java Web项目的核心文件。使用Struts2框架时,需要在web.xml中配置一个前段控制器FilterDispatcher,用于对Struts2框架进行初始化和处理所有的的请求。

 

Ø struts-plugin.xml:struts插件使用的配置文件。

 

 

 

7    Struts2的核心

Struts2的控制器组件是Struts2框架的核心。(所有MVC框架都是以控制器组件为核心的,Struts2的控制器由两部分组成:FilterDispatcher和业务控制器Action

 

 

 

 

 

第二章

一、    Struts2的配置

1     web.xml

是所有Java Web应用程序都需要的核心配置文件,起着初始化Servlet、Filter等Web程序的作用。

对于Struts2,需要在web.xml中配置一个前端控制器—FilterDispatcher,其中包含有以下初始化参数:

Ø config:要加载的XML配置文件的列表。如果没有设置config这个参数,Struts2默认加载struts-default.xml、struts-plugin.xml和struts.xml三个文件。

 

Ø actionPackage:以逗号分隔的Java包的列表,Struts2框架将扫描这些包中的Action类。

 

Ø configProviders:实现ConfigurationProvider接口的Java类的列表(以逗号分隔)。

 

Ø *:任何其他的参数被当作是Struts2的常量。

 

 

 

 

2    struts.xml

是整个Struts2框架的核心。struts.xml文件内定义了Struts2的系列Action。

定义Action时,指定该Action的实现类,并定义该Action处理结果与视图资源之间的映射关系。

包含的子元素有:

Ø include:是Struts2中组件化的方式,即可以将每个功能模块独立到一个XML配置文件中,然后用include节点引用。

 

Ø package:提供将多个Action组织为一个模块的方式。package的名字必须是唯一的。有如下属性:

name、extends、abstract、namespace

 

Ø 定义拦截器

有如下属性:

name、class

 

Ø 配置全局Results,如:

<global-results><result name=”input”>/error.jsp</result></global-results>

 

Ø 配置Action

有如下属性:

name、class、method

 

Ø 配置Result

一个Result表示一个可能的输出,有如下两个属性:

name:Result名称和Action中的返回的值相同

type:Result类型,不写则为superpackage的type,struts-default.xml中的默认为dispatcher

 

Ø Action的参数设置

配置Action可以将一个请求URL映射到一个action类。它只有一个name属性,该属性对应Action中的get/set方法。如:

<param name=”url”>http://www/sina.com</param>

 

总结:

(1) struts.xml文件的子元素有:

 

(*,?,+是通配符)

(2)struts.xml配置

配置内容分为3大部分:

l 管理元素:Bean配置,常量配置,包配置,命名空间配置,包含配置

l 用户请求处理元素:拦截器配置,Action配置,Result配置

l 错误处理元素:异常配置

 

 

 

3    struts.properties

是Struts2的属性配置文件,默认叫default.properties文件。它配置Struts2的默认设置。该文件提供一种更改框架默认行为方式的机制。

注意:struts.properties文件中定义的属性都可以在”web.xml”文件的”init-param”标签中设置,或在”struts.xml”文件的”constant”标签设置。该文件是只读的,但也可以修改。

struts.properties文件常用属性:

 

 

 

 

 

4    struts-default.xml

为Struts2框架提供了默认设置,是框架的基础配置文件。该文件包含在struts2-core-2.0.11.jar中,由框架自动加载。

 

 

 

 

5    struts-plugin.xml

Struts2为了扩展自身的功能,提供的类似Eclipse的插件机制,插件以Jar包的方式提供。

struts-plugin.xml文件在插件加载时,被Struts2框架自动读取。

 

 

 

 

 

6     配置Struts2的命名空间

(1)Bean(作用:Struts2以可配置的方式来管理Struts2的核心组件,从而允许开发者可以很方便的扩展该框架的核心组件

在struts.xml文件中定义bean时,通常有如下两个作用:

框架的IOC容器创建Bean的实例,然后将该实例注入框架的内部对象中。

通过Bean的静态方法向Bean注入值。

 

 

(2)常量

配置常量就是配置Struts2的属性。默认地,Struts2框架按照以下文件顺序搜索常量:越靠后的文件优先级越高,即顺序靠后的文件中的常量设置可以覆盖顺序靠前的文件的常量设置。

文件加载的顺序如下:

Ø struts-default.xml:存放在struts2-core-x.x.x.jar文件中(/WEB-INF/lib/struts2-core-xxx.jar)

Ø struts-plugin.xml:存放在struts2-xxx-x.x.x.jar等Struts2插件的Jar文件中。(/WEB-INF/lib/struts2-xxx-plugin.jar)

Ø struts.xml:Web应用中默认的Struts2配置文件。(/WEB-INF/classes)

Ø struts.properties:Struts2的属性配置文件。(/WEB-INF/classes)

Ø web.xml:Web应用的配置文件。(/WEB-INF/)

 

(3)包

Struts2框架使用包来管理组件,在包中可以配置多个Action,多个拦截器或者多个拦截器引用集合等。

 

(4)命名空间

Struts2通过为包指定namespace属性来为包下面的所有Action指定共同的命名空间,同一命名空间下不能有同名的Action。

Struts2先在指定的路径下找Action,如果找不到则会去默认的路径下找Action。(也就是说哪怕在指定的路径找不到Action,仍然可能得到正确的Action)

 

(5)包含(Include)配置

在struts.xml文件中使用include元素来包含其他的配置文件。

 

 

 

 

7    Result配置

(1)Action大部分都继承自ActionSupport类,在ActionSupport类中定义5个字段:

SUCCESS、NONE、ERROR、INPUT、LOGING

 

(2)Result类型

l dispatcher:默认的结果类型

l redirect:可以重定向到一个页面,另一个Action或一个网址。

l chain:用于把相关的几个Action连接起来,共同完成一个功能。

 

 

 

 

8    Struts2的异常机制

Struts2的异常机制通过在struts.xml文件中配置<exception-mapping>元素完成,配置该元素,需要指定两个属性:

exception:指定该异常映射所设置的异常类型

result:指定Action出现异常时,系统转入Result属性所指向的结果

注意:

输出异常使用Struts2的<s:property>标签来实现,代码为:

<s:property value=”exception.message”/>  输出异常对象本身

<s:property value=”exceptionStack”/>   输出异常堆栈信息

 

 

 

 

9   访问Struts2框架的文件的顺序:

服务器地址+工程名+namespace+命名空间下的action名

注意:

当使用默认的命名空间时(“”),action名的后缀不能省略。

 

 

 

 

10   多个Action间数据的传递,主要有两种方式:

(1)由于处于chain中的Action属于同一个HTTP请求,共享一个ActionContext,故可以在上下文中获取,在页面上可以直接使用。 手动获取的方法:

HttpServletRequest request = ServletActionContext.getRequest();

String s = (String)request.getAttribute(属性名);  或:

int 变量名 = Integer.valueOf(request.getParameter(“参数名”));

 

 

第三章   数据类型转换

1   Struts2的类型转换

Struts2类型转换机制的基础是OGNL表达式。

(1)使用OGNL表达式命名参数

Struts2框架会自动对输入数据按照user对象的属性的类型进行类型转换(如果user对象不存在,框架还会为此创建user对象),并用转换后的数据封装user对象。

 

(2)Struts2内置的类型转换器

l String

将int、long、double、boolean、的数组或String类型的数组或java.util.Date类型转换为字符串。

 

l boolean/Boolean

在字符串和布尔值之间进行转换

 

l char/Character

在字符串和字符之间进行转换

 

l int/Integer、float/Float、long/Long、double/Double

在字符串和数值型的数据之间进行转换

 

l date

在字符串和日期类型之间进行转换。

 

l array

由于数组元素本身就有类型,Struts2使用元素类型对应的类型转换器,将字符串转换为数组元素的类型,然后再设置到新的数组中。

 

l collection

如果不能确定对象类型,则假定集合元素类型为String,并创建新的ArrayList,存放所有的字符串。

 

 

(3)null属性的处理

当发现null引用时,null属性处理将自动创建对象。

如果Action上下文中存在键#CREATE_NULL_OBJECTS,并且其值为true(这个键只在com.opensymphony.xwork2.interceptor.ParameterInterceptor执行期间被设置),那么引发NullPointerException的OGNL表达式将被暂停求值。此时系统将通过创建所需对象的方法来自动尝试解决null引用。

处理null引用时将遵循的规则:

l 如果属性为Collection或者List,那么将创建一个ArrayList对象,并赋值给null引用

l 如果属性声明为Map,那么将创建一个HashMap对象,并赋值给null引用

l 如果null属性是一个具有无参构造方法的简单Bean,那么将使用BeanFactory的buildBean()方法创建一个Bean的实例。

(4)局部类型转换器

 

关于类型转换器的注册方式,主要有三种:

² 注册局部类型转换器:局部类型转换器仅仅对某个Action的属性起作用

² 注册全局类型转换器:全局类型转换器对所有Action的特定类型的属性都会生效

² 使用JDK1.5的注释来注册类型转换器,通过注释方式来生成类型转换器

 

局部类型转换器注册方式中,要注册类型转换器需提供的文件格式:

ClassName-conversion.properties(该文件与ClassName.class文件放于相同的位置,是一个Properties文件)

文件内容:

propertyName = 类型转换器类(1个)

如果propertyName是Map<Key,Value>类型,则写成:

Key_propertyName = 类型转换器类

Element_propertyName =  类型转换器类

 

 

(5)全局类型转换器

注册全局类型转化器提供一个xwork-conversion.properties文件,该文件也是Properties文件,其内容:

复合类型 = 对应类型转换器 (多个;“复合类型”指定需要完成类型转换的复合类,“对应类型转换器”指定所指定类型转换的转换器)

 

 

 

 

2   自定义类型转换器

(1)基本类型转换器

创建一个类型转换器,实现ognl.TypeConverter接口,该接口只有一个方法,即converValue()

public abstract interface TypeConverter{

public abstract Object convertValue(Map<String,Object> paramMap,

Object paramObject1,Member paramMember,String paramString,Object paramObject2,Class paramClass);

}

 

(2)基于Struts2的类型转换器

Struts2提供了一个StrutsTypeConverter的抽象类,这个抽象类是DefaultTypeConverter类的子类,开发者可以直接继承这个类来进行类型转换器的构造。

 

 

 

 

 

3   类型转换中的异常处理

(1)类型转换异常拦截器

Struts2提供类型转换异常处理机制,提供名称为conversionError的拦截器,这个拦截器被注册在默认拦截器栈(defaultStack拦截器栈)中。

当Struts2在类型转换过程中出现异常时,该拦截器就会进行拦截,并将异常信息封装成一个fieldError,然后在视图页面上显示出来。

(扩展:

Ø 名为conversionError的拦截器对应的类为org.apache.struts2.

interceptor.StrutsConversionErrorInterceptor,该类又继承自ConversionErrorInterceptor类,它只会在字段值不是null的情况下,才会把转换错误从ActionContext添加到Action的字段错误中。

Ø conversionError拦截器负责将对应错误封装成表单域错误(fieldError),并将错误信息放在ActionContext中。

Ø 当conversionError拦截器对转换异常进行处理后,系统会跳转到名为input的逻辑视图。因此需要为Action增加名为input的逻辑视图定义。

 

 

(2)处理类型转换错误

需要为Action增加名为input的逻辑视图定义,在struts.xml文件中的配置:

<action name=”user” class=”com.struts2.actions.UserAction”>

<result name=input>/input.jsp</result>

</action>

(注意:name=”input”是固定的,要改变。只能到Struts处理异常转换错误的action中修改返回值。而“/input.jsp”文件中的input是可变的名称,具体看你定义的处理异常的逻辑视图文件名)

 

 

(3)输出类型转换错误

为了在input视图对应的页面中输入转换错误,只需要在页面中使用<s:fielderror />标签即可输出该类型转换错误信息

 

 

 

 

4    使用类型转换注解

可用Struts2提供的类型转换注解来配置类型转换器,进而作为ClassName-conversion.properties文件的替代。

(1)使用类型转换注解

Struts2中用于类型转换的注解共6个,如下:

Ø TypeConversion注解:应用于属性和方法级别

Ø Conversion注解:可以让类型转换应用到类型(TYPE)级别

Ø Element注解:用于指定Collection或Map中的元素类型,该注解只能用于字段或方法级别

Ø Key注解:用于指定Map中的key的类型,该注解只能用于字段或方法级别

Ø KeyProperty注解:指定用于索引集合元素的属性名,该注解只能用于字段或方法级别

Ø CreateIfNull注解:指定在引用的集合元素为null时,是否让框架创建它。该注解只能用于字段或方法级别。

 

第4章   国际化与异常处理

1    在Java语言国际化API中,影响数据本地化的因素主要有两个:

(1)用户的语言环境

(2)用户的时区

 

 

 

2     Locale类

Locale类的static Locale getDefault()静态方法,用于获取本地系统默认的Locale对象,

static Locale[] getAvailableLocales()静态方法,返回所有已安装语言环境的数组。

 

 

 

3    资源包ResourceBundle类

获取资源包:用ResourceBundle类的getBundle()静态方法。

注意:

(1)getBundle()静态方法将按照下列顺序查找资源包:

l ChinaResource_zh_CN.class

l ChinaResource_zh_CN.properties

l ChinaResource_zh.class

l ChinaResource_zh.properties

l ChinaResource.class

l ChinaResource.properties

 

(2)java.util包还提供了ListResourceBundle和PropertyResourceBundle两个资源类,它们都是从ResourceBundle类中派生出来的。

 

 

 

 

4    Struts2框架加载资源文件的顺序

Struts2框架的资源文件具有一定的优先级。对于国际化信息的加载情况,可分为两类

(1)在Action中

如果国际化信息在Action中,则加载资源文件的顺序:

Action范围资源文件àAction的父类Action的资源文件àAction所实现的接口类的资源文件…

 

(2)在JSP文件中

如果国际化信息在JSP文件中通过text标签或者表单标签来定义,则加载资源文件的顺序分两种情况:

Ø 使用Struts2的i18n标签

从i18n标签指定的国际化资源文件中加载指定Key对应的值à查找struts.custom.i18n.resources常量所指定的value值,加载basename为该value的资源文件à直接输出这个Key的字符串值

 

Ø 没有使用Struts2的i18n标签

查找struts.custom.i18n.resources常量所指定的value值,加载basename为该value的资源文件à直接输出这个Key的字符串值

 

 

 

 

 

5   将用户注册国际化

即将用户注册程序改变为一个国际化的用户注册程序。

(1)国际化的配置文件

Ø 使用struts.xml文件

一般通过设置常量来实现,如:

<constant name=”struts.custom.i18n.resources” value=”globalMessages” />

 

Ø 使用struts.properties文件

struts.custom.i18n.resources = globalMessages

 

Ø 使用web.xml文件

<init-param>

<param-name>struts.custom.i18n.resources</param-name>

<param-value>globalMessages</param-value>

</init-param>

 

 

 

 

 

6    在文本中使用参数

Struts2为开发者提供了两种不同的在消息中设置参数的方式:

(1)占位符的方式(被动接受值)

占位符的方式就是Java中设置消息文本参数的方式,相当于使用从{0}到{9}的占位符。当使用MessageFormat类的format()方法格式化消息字符串时,参数信息内容传递进来,替换掉消息文本中的占位符。

 

(2)OGNL表达式(主动接受值)

在消息文本中使用OGNL表达式的语法是:${ms}

 

 

 

 

 

7    手动改变注册页面国际化

Struts2设定访问用户的语言环境locale的方式:

Struts2会根据ActionContext的getLocale()方法的返回值加载对应的资源文件。

因此,要改变当前的locale,只需要重新调用getLocale()方法并保存到ActionContext中即可。(即是通过使用Locale对象来设置语言环境,从而改变注册页面的显示语言)

 

 

 

 

 

8    Struts2的异常处理

Struts2提供一种声明式的异常处理方式,通过配置拦截器来实现异常处理机制。这种方式下,只需要在struts.xml文件中进行配置,Struts2便能够处理异常,然后响应相应的视图,在Action中无须编写任何异常处理代码

注意:

如果Action在处理请求的过程中出现异常,一个名为exception的拦截器将拦截该异常,并进行处理。Struts2框架在struts-default.xml文件中对exception拦截器进行了配置,代码为:

<interceptors>

<interceptor name="exception" class="com.opensymphony.

xwork2.interceptor.ExceptionMappingInterceptor"/>

</interceptors>

 

 

 

 

 

9    配置异常处理

(1)配置异常映射

在struts.xml文件中,使用<exception-mapping>元素,对exception拦截器进行异常映射配置。该元素含有两个必选属性:

exception:用来指定出现异常的类型(与<interceptor>中的class属性值对应)

result:用来指定出现异常时,Struts2返回给用户的视图名称。

 

(2)异常配置分类

Ø 全局异常映射

<global-exception-mappings>

<exception-mapping…/>

</global-exception-mappings>

Ø 局部异常映射

<exception-mapping>

 

(3)输出异常信息

输出异常对象本身:

<s:property value=”exception.message”/>

输出异常堆栈信息:

<s:property value=”exceptionStack”/>

 

第5章  Struts2中的拦路虎---拦截器

1    Struts2框架的大多数功能都是通过拦截器来实现的。如:避免表单重复提交,类型转换,对象组装,验证,文件上传等。

拦截器之所以称为“拦截器”,是因为它是在Action执行之前调用。(即在Action的execute()方法执行之前被执行,因此如果拦截器要得到页面中的元素,需要用request.getParameter()方法来获取)

 

 

 

 

2    Struts2的拦截器的执行

当请求到达Struts2的ServletDispatcher时,Struts2会查找相对应的配置信息,并实例化拦截器对象。串成一个列表(list),最后一个一个调用列表中的拦截器。

 

 

 

 

3   配置拦截器使用<interceptor name=”拦截器名” class=”拦截器实现类” />

如果在配置拦截器时传入拦截器参数,则需要在<interceptor…/>元素中使用<param…/>子元素。

注意:

(1)定义拦截器时,可以用<param…/>传入参数,引用拦截器时,也可以用<param…/>引入参数。如果这两个时机为同一个参数指定了不同的参数值,则使用拦截器时指定的参数值会覆盖定义拦截器时指定的参数值

 

(2)如果一个Action中定义了其他的拦截器引用,那么这个Action将不再使用默认的拦截器引用。如果Action想要在默认拦截器引用的基础上加上新的拦截器,那么就需要在Action中重新添加默认拦截器。

如:

<action name=”” class=””>

<interceptor-ref name=defaultStack />

<interceptor-ref name=”myInterceptorStack”/>

</action>

 

 

 

 

 

 

4   在struts.xml文件中加上“<include file=”struts-default.xml”/>以及<package…extends=”struts-default.xml”/>”,即继承了struts-default包,因此所有Action都会调用拦截器栈defaultStack

 

 

5     自定义拦截器

实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口有:

String intercept(ActionInvocation invocation)throws Exception 方法

注意:

当实现intercept(ActionInvocation invocation)方法时,可以获得ActionInvocation参数,这个参数又可以  被拦截的Action实例(invocation.getAction()方法),一旦获得Action实例,几乎获得全部的控制权:

可以实现将HTTP请求中的参数解析出来,设置成Action的属性(这个原是系统params拦截器干的事),也可以将HTTP请求中的HttpServletRequest实例和HttpServletResponse实例传给Action(这是servletConfig拦截器干的事)…

注意:

(1)params拦截器:

<interceptor name="params" class="com.opensymphony.

xwork2.interceptor.ParametersInterceptor"/>

servletConfig拦截器:

<interceptor name="servletConfig" class="org.apache.struts2.

interceptor.ServletConfigInterceptor"/>

 

(2)使用拦截器的两个步骤:

通过<interceptor../>元素来定义拦截器

通过<interceptor-ref../>元素来使用拦截器

 

 

 

 

 

6    拦截器剖析

在默认情况下,如果为某个Action定义了拦截器,则这个拦截器会拦截该Action内所有方法。

如果只需要拦截某些方法,则需要使用Struts2中的“方法过滤”。

 

 

 

 

7   实现方法过滤的拦截器

Struts2提供了一个MethodFilterInterceptor类,该类继承(extends)自AbstractInterceptor类,实现AbstractInterceptor类中的doInterceptor()方法。

protected String doIntercept(ActionInvocation ai)throws Exception{

return null;

}

注意:

实现方法过滤的拦截器与实现普通拦截器没有什么大的区别,只需要注意两个方面:

(1)实现方法过滤的拦截器需要继承MethodFilterInterceptor抽象类

(2)重写MethodFilterInterceptor抽象类的doIntercept()方法对Action定义的拦截逻辑。

在MethodFilterInterceptor抽象类中,额外增加了如下的两个方法:

² public void setExcludeMethods(String excludeMethods):排除需要过滤的方法。所有在excludeMethods字符串中列出的方法都不会被拦截。

² public void setIncludeMethods(String includeMethods):设置需要过滤的方法,所有在includeMethods字符串中列出的方法都会被拦截。

即:

<interceptor-ref name=”用引用的拦截器名”>

<param name=”excludeMethods”>方法一,方法二</param>

<param name=”includeMethods”>方法三,方法四</param>

</interceptor-ref>

 

注意:

当includeMethods和excludeMethods参数同时指定了一个方法名,则拦截器会拦截该方法。

 

 

 

 

 

8    拦截监听的结果

简单拦截器中,在execute()方法执行之前,执行之后的动作都定义在拦截器的intercept(ActionInvocation invocation)方法中。

为了精确定义在execute()方法执行之后再处理Result执行的动作,Struts2提供了用于拦截结构的监听器,这个监听器是通过手工注册到拦截器内部的。

实现拦截结构的监听器必须实现PreResultListener接口,代码为:

public class MyPreResultListener implements PreResultListener{

//定义在处理Result之前的行为

public void beforeResult(ActionIncocation invocation,String resultCode){

}

}

注意:

(1)resultCode这个参数是被拦截Action的execute()方法的返回值

(2)beforeResult()方法虽然获得ActionInvocation类型的参数,但Action此时已经执行完了,故通过这个参数来控制Action的作用不再那么明显。需要在拦截器中intercept(ActionInvocation invocation)方法中注册监听器:

invocation.addPreResultListener(new MyPreResultListener());

 

 

 

 

 

 

9    覆盖拦截器中特定拦截器的参数

有些时候,Action需要引用一个拦截器栈,当引用这个拦截器栈时,有需要覆盖这个拦截器栈中的某个拦截器的特定参数。

如:

(1)需要覆盖拦截器栈的“拦截器二”的name属性值,则:

<interceptor-ref name=”拦截器栈”>

<param name=拦截器二名称>改名后的拦截器名称</param>

</interceptor-ref>

 

(2)需要覆盖拦截器栈内特定的拦截器的属性值,则:

<interceptor-ref name=”拦截器栈”>

<param name=”拦截器名.参数名”>改名后的拦截器的属性值</param>

</interceptor-ref>

 

 

 

 

10   Struts2内置拦截器

这些拦截器以key-value对的形式配置在struts-default.xml文件中。

 

 

 

 

11   拦截器注解

利用拦截器注解来指定在Struts2中的Action执行之前和之后需要调用的方法。

 

Struts2在com.opensymphony.xwork2.interceptor.annotations包中定义了3个拦截器注解类型。

优点:

不必编写拦截器类,直接通过注解的方式来指定在Action执行之前和之后需要调用的方法。

 

Struts2提供3个拦截器注解类型:

(1)Before

标注一个Action方法,该方法将在Action的主要方法(如execute()方法)调用之前调用。如果标注的方法有返回值且不为null,那么它的返回值将作为Action的结果代码。

 

(2)After

标注一个Action方法,该方法将会在Action的主要方法以及result执行之后调用。如果标注的方法有返回值,那么这个返回值将会被忽略。

 

 

(3)BeforeResult

标注一个Action方法,该方法将在Action的主要方法调用之后,在result执行之前调用。如果标注的方法有返回值,那么这个返回值将会被忽略。

 

注意:

(1)这三个注解都有一个同名的参数priority,用于在“同一注解标注多个方法时,规定方法执行的先后顺序”:

参数

类型

是否必须

默认值

描述

priority

int

10

指定方法执行的优先级顺序

 

(2)这3个拦截器注解类型都只能应用到方法级别。

 


第6章   数据校验

1    手动完成输入校验

最直接的验证方法是编写Java代码对用户提交的数据进行校验。在Struts2中,验证代码是放在Action类中的,分为3中方式实现:

(1)在Action的execute()方法中进行验证

当一个请求到来时,在execute()方法中对用户输入数据进行验证。

 

(2)在validateXxx()方法中进行验证

在Struts2中,针对多个不同请求,可以使用同一个Action类的不同方法来进行处理,针对特定方法的输入数据的验证处理放于validateXxx()方法中,然后在execute()方法中调用该方法。

注意:

Ø validateXxx()方法由框架自动调用,它将在实际处理请求、实现业务逻辑的方法调用之前被调用。

Ø validateXxx()方法是由com.opensymphony.xwork2.interceptor.

DefaultWorkFlowInterceptor拦截器调用,不需要返回值,如果验证错误,将直接将它添加到Action的字段错误中即可。

 

(3)在validate()方法中进行验证

如果处理用户请求的多个Action方法的验证逻辑是相同的,那么可以让Action类实现com.opensymphony.xwork2.Validateable接口,然后在该接口中的validate()方法对用户输入数据进行验证。

validate()方法是由DefaultWorkFlowInterceptor拦截器调用的,DefaultWorkFlowInterceptor会检查Action是否实现了Validateable接口;如果实现了,就调用该接口的validate()方法。

注意:

Ø validate()方法在validateXxx()方法调用之后被调用,并且无论validateXxx()方法执行结果如何,validate()方法都会被调用。

Ø 调用validate()方法的拦截器DefaultWorkFlowInterceptor有一个excludeMethods参数,用于指定要排除的方法(要排除的方法指的是DefaultWorkFlowInterceptor拦截器的doIntercept()方法将不会被调用,因此validate()方法也就不会被调用了)

 

 

 

 

 

2    Struts2的输入校验流程:

(1)类型转换器负责对字符串的请求参数执行类型转换,并将这些值设置成Action的属性值。

(2)在执行类型转换过程中如果出现异常,将异常信息保存到ActionContext中,conversionError拦截器负责将其封装在fieldError里。

(3)通过反射调用validateXxx()方法

(4)调用Action类里的validate()方法

(5)如果以上步骤都没有出现fieldError,将调用Action里处理用户请求的处理方法;如果出现了fieldError,系统将转入input逻辑视图所指定的视图资源。

 

 

3    基本输入校验

(1)编写校验规则文件

Struts2的校验文件规则与Struts1的校验文件设计方式不同,Struts2中的每个Action都有一个校验文件,且校验文件命名规范为:

Ø Action级别校验命名格式:

ActionClassName-validation.xml

Ø Action中某个方法的校验命名格式:

ActionClassName-ActionAliasName-validation.xml

注:

ActionAliasName(Action别名)指的是在struts.xml文件中配置的Action name=”xxx”的xxx名称,而不是method=”xxx”的名称。

增加了校验文件后,其它部分无需任何修改,系统自动会加载该文件,对用户提交请求进行校验。

 

(2)国际化提示信息

Ø 通过key指定国际化提示信息

在每个<field-validator…/>元素中都包含一个必填的<message…/>子元素,该子元素的内容就是校验失败后的提示信息,为message元素指定key属性,该key属性指定国际化信息对应的key

<field-validator type=”requiredstring”>

<message key=”name.required” />

</field-validator>

 

Ø 通过ActionSupport的getText()方法获取国际化提示信息

<field-validator type=”requiredstring”>

<message>${getText(“name.required”)}</message>

</field-validator>

 

 

(3)校验文件的搜索规则

Struts2允许通过为校验规则文件名增加Action别名来指定具体需要校验的处理逻辑,即:

<ActionClassName>-<ActionAliasName>-validation.xml

如:

假设系统有两个Action:BaseAction和RegistAction,则系统搜寻规则文件顺序为:

BaseAction-validation.xml

BaseAction-别名-validation.xml

RegistAction-validation.xml

RegistAction-别名-validation.xml

Struts2搜索规则文件是自上而下,实际用的校验规则是所有校验规则的总和。如果两个校验文件中指定的校验规则冲突,则从后面文件中的校验规则取值。

 

 

 

 

4    内置校验器

Struts2提供13个验证器。Struts2默认的校验器注册文件在:

xwork-core-2.1.6.jar文件的com/opensymphony/xwork2/validators路径下的default.xml文件。

注意:

通过添加一个validation.xml文件到WEB-INF/classes路径下,可完成注册校验器,实现开发者开发的一个子集的校验器。此时因为Struts2系统在WEB-INF/classes路径下找到了一个validation.xml文件,故不会再加载系统默认的default.xml文件。(也就是说开发者只要注册了validatiuon.xml文件,则不会加载系统默认的default.xml文件)

 

 

 

 

 

5    Struts2内置的13个验证器

必填验证器required

必填字符串验证器requiredstring

字符串长度验证器stringlength

整数验证器int

双精度浮点数验证器double

日期验证器date

表达式验证器expression

字段表达式验证器fieldexpression

正则表达式验证器regex

邮件验证器email

网址验证器url

visitor验证器

转换验证器conversion

 

 

 

 

6     开发自己的验证器

(1)Validator接口

验证程序必须实现Validator接口,它是com.opensymphony.xwork2.validator包的一部分。

Validator、FieldValidator和ShortCircuitableValidator接口属

于com.opensymphony.xwork2.validator包;其他的组件属于

com.opensymphony.xwork2.validator.validators包。

 

(2)ValidatorSupport类

该类实现了Validator接口,在ValidatorSupport类中增加了几个方法:

getFieldValue():返回Object对象name字段的值

addActionError():增加一个动作错误信息

addFieldError():增加一个字段错误信息

注意:

FieldValidatorError类扩展了ValidatorSupport类,并新增了propertyType和fieldName两个属性。

 

 

(3)RequiredStringValidator类

在对输入数据配置字符串非空验证校验器requiredstring时就是用RequiredStringValidator类实现的。

 

 

 

 

 

7   使用visitor字段验证器复用验证

VisitorFieldValidator验证器:

简称visitor验证器,它可以提高代码的可重用性,告诉验证框架查找Action的属性所属的类型对应的验证文件并进行验证。VisitorFieldValidator可以处理简单的对象属性,也可以处理对象集合或对象数组。

 

 

 

 

 

8    使用验证注解

Struts2内置的13个验证器都有对应的注解。

 

 

 

 

9    Struts2提供了两种方式来配置校验规则:

(1)字段校验器风格:以<field…/>元素为基本子元素

(2)非字段校验器风格:是以校验器优先的配置方式,这种配置方式下,校验规则文件的根元素包含多个<validator…/>元素,每个<validator…/>元素定义了一个校验规则。

短路校验:只需在<validator…/>元素或<field-validator…/>元素增加short-circuit=”true”即可。


第7章   Struts2中完整的OGNL

1    OGNL

OGNL是一种用于访问和设置对象数据的强大的表达式语言,它可以自动导航对象图的结构,实现调用对象方法,操作集合,访问类的静态成员等。

OGNL表达式的基础单元就是导航链(Navigator Chain),简称为链。最简单的链由三部分组成:

属性名、方法调用和数组索引。

 

 

 

 

2    OGNL的三要素

(1)表达式(Expression)

是整个OGNL的核心,所有的OGNL操作都是通过解析表达式后进行的。表达式指定了OGNL操作要做的工作。

最基本的表达式是将对象的引用值用“.”串联起来。

常用的OGNL表达式:

Ø 常量

包括:字符串常量、字符常量、数值常量、布尔常量、null常量

 

Ø 基本对象树的访问

通过“.”将对象的引用串联起来进行

 

Ø 对容器变量的访问

通过“#”符号加上表达式进行

 

Ø 操作符号

OGNL表达式中能使用的操作符基本和Java里的操作符一样,除了+ - * / ++ -- == !=外,还能使用mod in not in等。

 

Ø 访问JavaBean的属性:

² name:相当于Java代码:employee.getName()

² address.country:相当于Java代码:employee.getAddress.getCountry() 

 

Ø 容器、数组、对象

ü OGNL支持对数组和ArrayList等容器的顺序访问,如:

group.users[0]

ü OGNL支持对Map的按键值查找,如:

#session[mySessionPropKey]

ü OGNL还支持容器构造的表达式

{“green”,”red”,”blue”}   //构造一个List

#{“key1”:”value1”,”key2”:”value2”,”key3”:”value3”}   //构造一个Map

ü 通过任意类对象的构造函数进行对象新建

new java.net.URL(“http://localhost”)

 

Ø 对静态方法或变量的访问

格式:@class@member或者@class@method(args),如:

@com.java.core.Resource@ENABLE   //调用静态字段

@com.java.core.Resource@getAllResources()   //调用静态方法

 

Ø 方法调用

可以通过类似Java的方法调用进行,也可以通过传递参数的方式,如:

user.getName();

group.containsUser(requestUser);

 

Ø 调用构造方法

OGNL支持对构造方法的调用,用于创建一个新的对象,可以像Java一样用new操作符来创建一个对象,但要注意类名必须使用完整的限定(带包名),如:

<s:property value=”new com.struts2.action.model.Dog()” />  //创建一个Dog对象

 

 

(2)根元素(Root Object)

根对象可以理解为OGNL要操作的对象。

 

 

(3)上下文环境(Context)

在OGNL的内部,所有的操作都会在一个特定的环境中进行,这个环境就是OGNL的上下文环境(Context)。即这个上下文环境规定这个OGNL的操作地点。

OGNL的上下文环境是一个Map结构,称为OgnlContext

 

 

 

 

 

3    OGNL对集合的操作

(1)创建集合

Ø 创建列表

List list = new ArrayList(3); 

{'Marry’,’Jack’,’Rose’}[0]

 

Ø 创建数组

String array = new String[]{“hello”,”nihao”}

array[0]

 

Ø 创建Map

Map使用特殊的语法来创建:

#{“key”:”value”,…}

Map通过key来访问,如:map[“key”]或map.key

注意:

如果想指定创建的Map类型,可以在左花括号前制定Map实现类的类名,如:

#@java.util.LinkedHashMap@{key”:”value,...}

 

 

(2)集合的伪属性

OGNL提供的一些伪属性,相当于对Java集合API的方法的调用。

有:

集合类型

伪属性

List,Set,Map

size,isEmpty

List

iterator

Map

keys,values

Set

iterator

Iterator

next,hasNext

Enumeration

next,hasNext,nextElement,hasMoreElements

 

 

 

(3)投影和选择

投影就是选出集合中的每个元素的相同属性组成新的集合。语法:

collection.{XXX}  // XXX是这个集合中的每个元素的公共属性

如:

group.userList.{username}      

 

选择就是过滤满足selection条件的集合元素,类似于关系数据库的记录操作。语法:

collection.{X YYY}  

//X为选择操作符,YYY为逻辑表达式

注意:

选择操作符有三种:

?:选择满足条件的所有元素

^:选择满足条件的第一个元素

$:选择满足条件的最后一个元素

如:

#employee.{?#this.salary>3000}

 

 

 

 

 

4    lambda表达式

是一个匿名函数,可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。

语法:

:[表达式]

注意:

OGNL中的Lambda表达式只能使用一个参数,但这个参数可以通过#this变量来引用。OGNL将lambda表达式看作常量。

如:

声明一个使用递归来计算阶乘的函数: 

#fact = :[#this<=1?1:#this*#fact(#this-1)]

调用它:

#fact(30H)     //调用上述表达式,#this变量的初始值为30H

// lambda表达式是[]中的部分,#this变量代表表达式的参数,它的初始值是30H(H表示BigInteger常量),每次递归调用表达式都将参数的值减1。

 

 

 

 

 

5    Struts2对OGNL表达式的增强

Struts2的OGNL之上提供的最大附加特性就是支持值栈(ValueStack)。在OGNL上下文中只能有一个根对象,Struts2的值栈则允许存在许多虚拟根对象。

 

(1)值栈(ValueStack)

Struts2将OGNL上下文设置为Struts2中的ActionContext,并将值栈作为OGNL的根对象。值栈是Struts2的核心。

值栈通过接口com.opensymphony.xwork2.util.ValueStack来定义,对应的类是com.opensymphony.xwork2.util.OgnlValueStack

注意:

Ø 直接访问OGNL上下文中的根对象时,不需要使用“#”来标记。,而引用上下文中的其他对象需要使用“#”来标记。

Ø 值栈ValueStack是 上下文的根对象,故可以直接访问。

Ø Struts2提供OGNLPropertyAccessor(ognl.ObjectPropertyAccessor)接口来访问值栈中的对象。Struts2提供的实现类是静态的内部类OgnlValueStack.ObjectAccessor,它可以自动查询栈内的所有对象(从栈顶到栈底),直到找到一个所查找的属性的对象。即是说,值栈ValueStack中的任何对象都可以直接访问,而无需使用“#”。

 

 

(2)[N]语法

[N].xxx语法:表示“获取栈中索引为N的对象”,而非“获取栈中索引为N的对象”

 

 

(3)top关键字

是Struts2引入的新的关键字,用于获取栈顶的对象。如:

[0].top:获取Object0

[1].top:获取Object1

 

 

(4)访问静态成员

Struts2允许不指定完整的类名,而是通过vs前缀来调用保存在栈中的静态字段和静态方法。如:

@vs@FOO_PROPERTY

//vs表示值栈ValueStack,如果只有vs表示使用栈顶对象的类,如果在vs后面跟上一个数字,那么将使用栈中指定位置处的对象类

注意:

Struts2中提供了一些访问静态成员的方式,但默认是关闭的。需要使用时,在Struts2的配置文件struts.xml中添加如下设置:

<constant name=struts.ognl.allowStaticMethod Access value=true />

设置之后,可以用以下表达式访问静态成员:

<s:property value=@com.struts2.util.DBUtil@getName()

 />   //访问静态方法

<s:property value=@com.struts2.util.DBUtil@Index_Title />  //访问静态常量

 

 

(5)值栈的Action实例

<s:property value=”name” />

//输出栈顶的Action实例的name属性值

 

 

(6)Struts2中的命名对象

这些命名对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型,有:

Ø parameters

用于访问请求参数,如:#parameters['id]或#parameters.id

 

Ø request

用于访问请求属性。如:#request[id]或#request.user

 

Ø session

用于访问session属性

 

Ø application

用于访问application属性

 

Ø attr

如果PageContext可用,则访问PageContext,否则依次搜索request,session和application对象

 


第8章  Struts2的标签库

1   控制标签

(1)if/elseif/else

<s:if test=”表达式”>标签体</s:if>

<s:elseif test=”表达式”>标签体</s:elseif>

<s:else>标签体</s:else>

 

(2)iterator

主要用于集合的迭代,这里的集合包括List,Set和数组,可对Map类型的对象进行迭代输出。

如:

<s:iterator value=”{‘端午’,’中秋’}” id=”name” status=”status”>

 

(3)append

可以将多个集合对象拼接起来,组成一个新的集合。

append标签如果指定了id属性,那么合并后的迭代器将保存到OgnlContext中。

 

(4)merge

用于将多个集合拼接成一个新的集合。

merge标签将合并后的迭代器将被保存到OgnlContext中。

 

(5)generator

根据separator属性指定分隔符,将val属性指定的值进行拆分,然后生成一个迭代器,压入到值栈的栈顶。即generator将一个字符串转换成一个集合。

在标签的内部,整个临时生成的集合位于ValueStack的顶端,一旦标签结束,该集合将被移出ValueStack。

 

(6)subset

用于取得集合的子集,该标签的底层通过org.apache.Struts2.util.SubsetIteratorFilter类提供实现。

 

(7)sort

对指定的集合元素进行排序

 

 

 

 

 

2    数据标签

(1)property

输出value属性的值,如果没有指定value属性,则默认输出ValueStack栈顶的值。

 

(2)set

用于将某个值放入到指定的范围内,如application范围,session范围等

 

(3)push

将某个值放到ValueStack的栈顶,从而实现最简单的访问。

 

(4)param

为其他标签提供参数,如:append标签,merge标签,bean标签和include标签。

格式有两种:

<param name=”username”>Jack</param>

<param name=”username” value=”Jack” />

 

(5)bean

创建一个bean实例。如果bean标签还指定了id属性,则创建的JavaBean对象将被放入OgnlContext中。

 

(6)action

指定Action的名字和可选的名称空间,action标签允许在JSP页面中直接调用Action。

<s:action name=”first” executeResult=”true”>

 

(7)include

将一个JSP或者Servlet包含到本页面。

<s:include value=”1.jsp”>

 

(8)url

用于生成一个URL地址,可以通过为url标签指定param子元素,从而向指定URL发送请求参数。

(9)i18n和text

用于为国际化提供支持。i18n标签用于将一个资源包放入值栈,text标签用于从资源包中获取消息。

<s:i18n name=”ApplicationResources”>

<s:text name=”title” />

</s:i18n>

注意:i18n标签将基名为ApplicationResources的资源包放入值栈中,text标签从资源包中获取键为title的文本消息。

 

(10)date

用于格式化输出一个日期,除了可以直接格式化输出一个日期外,date标签还可以计算指定日期和当前时刻之间的时差。

 

(11)debug

用于辅助调试,它可以在页面中生成一个Debug超链接,单击这个超链接,可以查看到ValueStack和ActionContext中所有的对象。

 

 

3    主题和模版

Struts2支持三种模版引擎:

Ø ftl(默认):基于FreeMarker的模版引擎

Ø vm:基于Velocity的模版引擎

Ø jsp:基于JSP的模版引擎

 

Struts2内置的四种主题:simple,xhtml,css_xhtml和ajax主题。

注意:

simple主题是最底层的结构,提供了简单的HTML元素支持。

xhtml主题是Struts2默认的主题。

css_xhtml主题不是采用表格对表单元素进行布局,而是采用css和<div>对表单元素进行布局。

ajax主题也是对xhtml主题进行扩展,并增加了自己特有的特性。ajax主题的Ajax支持是以Dojo和DWR为基础的

 

 

 

4    表单标签

Struts2的所有表单标签处理类都继承自UIBean类,UIBean包含一些通用属性:

Ø 模版相关的属性

Ø JavaScript相关的属性

Ø 工具提示相关的属性

Ø 通用属性

有标签:

(1)form

用于输出一个HTML输入表单

 

(2)textfield

用于输出一个HTML单行文本输入控件,相当于<input type=”text”…/>

 

(3)password

用于输出一个HTML口令输入控件。

 

(4)textarea

输出一个HTML多行文本输入控件。相当于<textarea…/>

 

(5)select

输出一个HTML列表框

 

(6)optgroup

作为select标签的子标签,用于创建选项组。

 

(7)radio

输出一组HTML单选按钮,相当于一组:<input type=radio”…/>

 

(8)checkbox

用于输出一个HTML复选框,相当于:

<input type=”checkbox”…/>

 

(9)checkboxlist

创建一系列复选框。

 

(10)combobox

用于生成一个单行文本框和下拉列表框的组合。

 

(11)doubleselect

输出关联的两个HTML列表框,第二个列表框显示的内容随第一个列表框选中的选项而变化。

 

(12)optiontransferselect

用于创建一个选项转移列表组件。

(13)label

xhtml主题提供的label标签输出两个HTML的label标签分别位于一行的两列,左列的label标签起提示作用,右列的label标签用于显示只读的action属性数据。

 

(14)file

用于输出一个HTML文件选择框,相当于:<input type=”file”…/>

 

 

(15)head

输出对应主题的HEAD部分的内容。如果有些主题需要包含特定的CSS和JavaScript,可以使用head标签来输出这些代码。

 

 

(16)token

用于防止多次提交表单(避免刷新页面时多次提交),如果需要该标签起作用,则应该在Struts2的配置文件启用了TokenInterceptor拦截器,获知TokenSessionInterceptor拦截器。

实现原理:

在表单中添加一个隐藏域,每次加载页面时,该隐藏域的值都不相同。TokenInterceptor拦截器拦截所有用户请求,如果两次请求时该token对应隐藏域的值相同,则阻止表单提交。

token标签无需在页面上生成任何输出,也无需开发者手动控制,因此使用该标签无需指定任何属性。

 

 

(17)updownselect

该标签类似于select标签,区别是该标签生成的列表框可以支持选项的上下移动。

 

(18)hidden

输出一个HTML隐藏表单元素,相当于HTML代码:<input type=”hidden”…/>

 

 

(19)submit

输出一个提交按扭。submit标签自己特有的属性如:

input,image和button

 

 

(20)reset

用于输出一个重置按钮,一般与form标签结合使用提供表单的重置功能。

 

 

 

 

 

 

5    非表单标签

包括:component,a,actionmessage,actionerror等。

(1)component

用于使用自定义的组件。如果开发者经常需要使用某个效果片段,就可以考虑将这个效果片段定义成一个自定义组件,然后在页面中使用component标签来使用该自定义组件。

 

(2)a

该标签用于创建一个HTML超链接。a标签提供了一个String类型的href属性,该属性指定链接的URL地址。

<s:a href=”addUser.action”>添加用户</s:a>

 

 

(3)actionmessage,actionerror和fielderror

这三个标签用法几乎一样。它们都是用于输出消息的,区别是:

actionmessage用于输出Action实例的一般性消息;

actionerror标签用于输出Action实例的错误消息;

fielderror标签用于输出Action实例字段的错误消息。


第9章  1    文件上传 轻松实现文件上传和下载

 

表单元素的enctype属性:指定的是表单数据的编码方式,该属性的三个值:

Ø application/x-www-form-urlencoded:默认的编码方式,它只处理表单域的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。

 

Ø multipart/form-data:以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。

 

Ø text/plain:在表单的action属性为mailto:URL形式时比较方便,这种方式主要使用于直接通过表单发送邮件的方式。

 

 

 

 

2   Struts2对文件上传的支持

Struts2默认使用的上传组建是Apache组织的commons-fileupload组件,该组件支持任意大小的文件的上传。

Struts2还支持两种文件上传组件:pell和cons,可以通过配置struts.multipart.parser属性来切换Struts2使用的上传组件。

 

 

 

 

 

3   FileUploadInterceptor

Struts2提供了一个文件上传拦截器:org.apache.struts2.interceptor.FileUploadInterceptor,它负责调用底层的文件上传组件解析文件内容,并为Action准备与上传文件相关的属性值。

处理文件上传的Action应该提供的三个属性:

Ø image:java.io.File类型,已上传文件的File对象

Ø imageFileName:上传文件的文件名

Ø imageContentType:上传文件的内容类型(MIME类型)

 

 

 

 

4    上传文件过滤

Struts2提供了FileUploadInterceptor拦截器,通过配置该拦截器可以实现文件过滤。

FileUploadInterceptor拦截器是默认的defaultStack拦截器的一员。

FileUploadInterceptor拦截器有两个重要的属性:

Ø maximumSize:上传文件的最大长度(以字节为单位),默认为2MB

Ø allowedTypes:以逗号分隔的内容类型的列表,如果没有指定该参数,则允许任何上传类型

注意:

如果上传的文件的长度大于struts.multipart.maxSize属性的值,那么底层的commons-fileupload组件将抛出org.apache.commons.fileupload.FileUploadBase$SizeLimit ExceededException异常,上传文件拦截器捕获到该异常后,将直接把该异常的消息设置为Action级别的错误消息。

如果在页面使用<actionerror>标签,将输出异常错误信息。

注意:

与上传文件有关的错误信息已经在struts-message.properties文件里预定义好,该文件被打包在Struts2的系统JAR文件里,有以下内容:

Ø struts.message.error.uploading:文件不能上传的通用错误信息

Ø struts.message.error.file.too.large:上传的文件长度太大的错误信息

Ø struts.message.error.content.type.not.allowed:当上传的文件不匹配指定的内容类型时的错误信息

 

 

 

 

 

5   同时上传多个文件

上传一个文件的动作类必须有三个属性:

File [inputName]File

String [inputName]FileName

String [inputName] ContentType     //[inputName]是JSP页面上file标签的名称

 

如果上传多个文件,可以使用数组或java.util.List。

使用数组(File数组和String数组):

private File[] image;

private String[] imageFileName;

private String[] imageContentType;

 

使用List:

private List<File> image = new ArrayList<File>();

private List<String> imageFileName = new ArrayList<String>();

private List<String> imageContentType = ArrayList<String>();

 

 

 

 

6    文件下载

Struts2提供了stream结果类型,该结果类型是专门用于支持文件下载功能的。指定stream结果类型时,需要指定一个inputName参数,该参数指定一个输入流为被下载文件的入口。

 

(1)StreamResult

Struts2通过org.apache.struts2.dispatcher.StreamResult结果类型来支持文件下载。StreamResult有参数:

Ø contentType:发送给Web浏览器的数据流的MIME类型(默认为text/plain,即下载文件的内容类型)

Ø contentDisposition:用于控制文件下载的一些信息,可选设置有:inline,filename=”下载文件名”和attachment。(注意:attachment表示弹出“文件下载”的对话框,inline表示下载文件在本页面内部打开)

Ø contentLength:数据流的长度,以字节为单位,即下载文件的长度

Ø inputName:Action中用来下载文件的属性的名字,该属性的类型是InputStream,默认值为inputStream

Ø bufferSize:文件数据从输入复制到输出的缓冲区的大小,默认为1024字节

 

 

(2)配置文件下载Action

只需在配置普通的Action的基础上额外加入download的拦截器引用。此外,配置一个类型为stream的结果。


第10章   避免表单重复提交和等待页面

1   token标签

Struts2框架提供token标签,根据每次请求的内容,将生成一个唯一性的隐藏字段value值,字段长度为32字节。 token标签通过这个隐藏表单域,实现在服务器避免表单重复提交。

注意:

token标签可以与TokenInterceptor,TokenSessionInterceptor或者ExecuteAndWaitInterceptor等配合使用。

(1)TokenInterceptor

在此使用org.apache.struts2.interceptor.TokenInterceptor拦截器防止用户重复提交的操作。

TokenInterceptor拦截器的处理请求过程除了需要为Action配置这个拦截器的引用外,同时还需要配置“invalid.token”结果映射,以便拦截器在表单重复提交时,将请求转向这个结果视图。

 

(2)TokenSession StoreInterceptor

对表单重复提交后会向用户显示一条错误消息,再次需要使用org.apache.struts2.interceptor.TokenSessionStoreInterceptor拦截器。

tokensession拦截器扩展了token拦截器,但是tokenSession拦截器不会返回一个特殊的结果,也不会添加一个动作错误,只是阻断后面的提交

 

 

 

 

2    设置等待页面

ExecuteAndWaitInterceptor拦截器

能够在用户请求提交之后执行一个耗时较长的Action在后台执行,而且向用户显示一个执行的进度信息。

当用户提交一个表单请求时,ExecuteAndWaitInterceptor拦截器将会创建一个新的线程来处理执行的Action,同时向用户显示一个等待的消息内容。

注意:

(1)ExecuteAndWaitInterceptor是基于每个session工作的,也就是说同一个Action不可以在同一个session中运行一次或者多次。

 

(2)ExecuteAndWaitInterceptor拦截器已经在struts-default.xml文件中定义,但没有包含在defaultStack拦截器栈中,因此需要为Action配置引用这个拦截器。

 

(3)ExecuteAndWaitInterceptor拦截器有如下几个常用属性:

Ø threadPrority:指定线程的优先级别,默认为Thread.NORM_PRIORITY

Ø delaySleepInterval:该参数只能与delay参数使用,用来检查执行的程序是否执行完毕的间隔时间,默认为100毫秒。

Ø delay:显示等待页面初始的等待延迟时间,默认是没有等待时间。


第11章   Struts2集成Spring与Hibernate

1    使用Hibernate查询数据

Hibernate不仅可以保存数据,也可以查询数据。Hibernate也支持条件查询,条件查询需要使用以下三个类或接口:

Criteria;代表一次条件查询

Citerion:代表一个查询条件

Restrictions:产生查询条件的工具类

 

 

 

 

2    Struts2与Hibernate的整合

通过中间层组件。中间层组件负责实现Web应用中的大部分业务操作。具体,中间层分为两层:

DAO层:用于底层持久化实现。

业务逻辑层:用于实现业务逻辑。

 

 

 

 

3    Spring框架组件(7个)

Spring Core, Spring Context, Spring AOP,  Spring DAO,  Spring ORM,  Spring Web,  Spring Web MVC

 

 

 

4   Springd的IoC容器

Spring框架的核心基于控制反转原理。

控制反转:是一种将组件依赖关系的创建和管理置于程序外部的技术,即由容器控制程序之间的关系,而不是由代码直接控制。


第12章   整合JFreeChart

 

 

 

第13章   Struts2的Ajax

1    Ajax的主要优点

(1)有针对性的数据传输

例如;新用户名的检测,如果使用Ajax技术进行,它可以只将用户名信息传送到服务器,而不需要传送整个表单数据。

 

(2)无刷新更新页面

在不重新载入整个页面的情况下用JavaScript操作DOM最终更新页面。

 

(3)基于公开的标准

Ajax技术基于已经被各大浏览器和平台都支持的公开标准的技术。

 

(4)跨平台浏览器的兼容性

 

(5)技术独立性

 

 

 

 

 

2    Struts2的Ajax校验建立在DWR和Dojo两个框架之上,DWR负责实现在JavaScript中调用远程Java方法,Dojo则负责实现页面上的效果。

(1)DWR

DWR(Direct Web Remoting)是一个改善Web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包括Ajax技术的网站。它可以允许在浏览器里的代码使用运行在Web服务器上的Java函数,好像它就在浏览器一样。

注意:

Ajax输入校验不是基于客户端,而是基于服务器端,是以异步方式实现的校验方式

Struts2的Ajax输入验证使用的是DWR框架。

 

 

 

 

3   配置DWR

仅仅将DWR的Jar包加到项目中是不能使用DWR框架的,还需要在项目的web.xml文件中配置DWR的核心Servlet。

 

4    JSON

XML的作用就是利用规范的文档来格式化数据内容,所以在使用XML时,需要编写很多的格式内容。

JSON与XML的比较:

从数据传输量上,JSON优于XML,JSON更轻量级,它没有像XML那样多的Open和Closing标记。

从对数据的解析上,JSON优于XML。

结论:

JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON是理想的数据交换语言。

 

 

 

 

5   JSON的格式

(1)对象Object

{ }

 

(2)数组

[ ]

 

(3)值

“”

 

(4)字符串

“”

 

(5)数值

与Java的数值相似,但不区分整数值和浮点数值,也不支持八进制和十进制格式。

 

 

 

 

6    Dojo

是开源的JavaScript工具包,由许多模块组合成,可以实现完整的轻量级窗口组件及很多功能。

Dojo的包加载机制可以实现动态加载所需模块。

Dojo框架

不仅存在于抽象层,而且是独立存在的。不只是提供一些库、方法和功能,而且保证代码只包含所需的部分,让代码简洁,更有效率。

 

 


0 0
原创粉丝点击