编写Struts2第一个程序

Struts2是目前最流行的MVC框架,吸收了传统Struts和WebWork两者的精华,基于Struts2来进行开发可以大大减少开发时间,提高开发效率,并降低后期维护时间和精力。Struts2如此优秀,但在MVC框架领域里还有两个另外替代者:JSF和Tapestry。

本文详细介绍Model 1和Model 2架构模式的优缺点,然后介绍常用的MVC框架以及对Struts2的简单介绍。详细介绍如何设置Struts2的开发环境以及配置web.xml和struts.xml配置文件。

重点内容:

Model 1和Model 2架构

MVC模式

搭建Struts2开发环境

Struts2框架

1.Model 1架构模式

Model 1的核心是JSP文件,使用Model 1开发的项目包含大量相互独立的JSP文件和少部分JavaBean。使用Model 1进行开发时,JSP负责接收表单参数、处理业务逻辑并最终将结果返回给客户浏览器端。

Model 1的程序流程比较容易理解。用户提交信息给JSP页面,JSP接受用户提交的值并通过JavaBean连接数据库并操作数据库,然后将结果返回给用户,如图所示。

2.Model 2架构模式

Model 2是通过面向对象技术实现MVC模式从而扩展JSP/Servlet形成的一种新的架构模式。MVC中包含三个基本组成部分,分别是Model(模型)、View(视图)、Controller(控制器)。

Model 2的程序流程相对Model 1来说要稍微复杂。用户提交信息给控制器,控制器决定使用哪个模型,调用该模型完成业务逻辑,然后通过决定调用哪个视图,并最终返回给用户,如图所示。

3.常用的MVC框架

在MVC框架出现之前,开发人员都是通过JSP+Servlet+JavaBean的方式来实现MVC模式。但是随着时间的发展,越来越多的问题暴露出来,其中最重要的就是缺少一个标准,每个社区、公司都有自己的一套标准,很难进行统一开发。Struts框架的出现改变这种格局,开发人员可以通过它为业务应用的每一层提供支持。

Struts框架是Apache基金会中Jakarta项目组的一个开源项目,它基于MVC模式开发,能够帮助Java开发人员快速的通过MVC模式开发Web项目。Struts框架和其他Java架构一样,采用面向对象设计,并将MVC模式运用得淋漓尽致。Struts开源项目的创立者就是希望通过对该项目的研究,改进和提高JSP、Servlet、标签库以及面向对象的技术水准。同时Struts框架是一个开源项目,开发人员可以更深入的了解其内容实现机制。

4.Struts2框架简介

Struts2是Struts的下一代产品。最初提案Struts Ti所设想的发展方向,在Struts的现有代码的基础上是很难完成的。在发起提案的时候,Patrick Lightbody把多个不同的Web框架的领导者邀请到了一起,希望大家能够达成共识,协力完成一个通用框架。虽然最终由于各种原因,Patrick Lightbody的愿望未能实现,但是WebWork和Struts却发现了二者在技术与开发人员这两个层面上的共同之处,不久之后,两个项目就在WebWork的技术基础上进行了合并,一个全新的Struts2框架就这样诞生了。

Struts2的体系结构与Struts1的体系结构的差别是巨大的。Struts2是以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也是可以使得业务逻辑控制器能够与Selvet API完全的脱离开,所以Struts2可以理解为是WebWork的更新产品。因为Struts2和Struts1有着太大的变化,但是相对于WebWork,Struts2只有很小的变化,所以如果是以前的WebWork开发人员能方便的过渡过来。

搭建Struts2开发环境

1.下载并安装Struts2框架

Struts2框架是由Apache开源组织开发并负责维护的,所以可以登录Struts的官方站点http://struts.apache.org。

在Struts官方站点中可以看到Struts的Download大图标,点击此图标,进入Struts下载界面,在该选项下可以看到现在Struts2的最

新版本是struts-2.3.24.1。单击“struts-2.3.24.1-all.zip ”链接下载struts-2.3.24.1-all.zip。

2.配置web.xml

要想在项目中添加Struts2支持,还需要编辑Web项目中的web.xml配置文件,在配置文件中增加Struts2核心Filter的配置。编辑后的web.xml配置文件代码如下。

    <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter> <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

3.配置struts.xml

struts.xml是Struts2框架的核心配置文件,主要负责管理Struts2框架下的业务控制器Action。struts.xml需要放置在项目的WEB-INF/classes路径下,如果是使用Eclipse等开发工具来开发的话,则放置在src根目录下。

创建完struts.xml配置文件后,需要在该文件中添加XML规范、DTD以及根目录信息。代码如下所示。

<?xml version="1.0" encoding="UTF-8" ?><!-- XML声明 -->

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts><!-- 根节点 --> </struts>

Struts2类型转换和输入校验

类型转换和输出校验是Struts2的一个非常重要的部分。通过类型转换能够将表单参数转换成Java类中各种类型,而通过输入校验能够对表单参数进行合法性判断,从而过滤掉“不良”数据。本章将详细介绍Struts2的内建类型转换器和自定义类型转换器。还将介绍如何手动添加校验代码来完成校验和通过校验框架来完成校验。

重点内容:

Struts2内建类型转换器

自定义类型转换器Re

手动添加校验代码来完成校验

通过校验框架完成输入校验

Struts2类型转换基础

1.类型转换的意义

Web应用程序的交互都是建立在HTTP之上的,互相传递的都是字符串。也就是说服务器接收到的来自用户的数据只能是字符串或者是字符数组,而在Web应用的对象中,往往使用了多种不同的类型,如整数(int)、浮点数(float)、日期(Date)或者是自定义数据类型等。因此在服务器端必须将字符串转换成合适的数据类型,服务器端完成处理后,又需要将其他数据类型转换为String,然后传递给客户端进行显示,具体流程如图所示。

2.内建类型转换器简介

Struts2为常用的数据类型提供了内建的类型转换器,所以根本不用自定义转换器。对于内建的转换器,Struts在遇到这些类型时,会自动去调用相应的转换器进行类型转换。下面来看Struts2提供了哪些内建的类型转换器,具体如下。

q1、基本数据类型以及其封装类。

q2、日期类型。

q3、集合(Collection)类型。。

q4、集合(Set)类型。

q5、数组类型。

3.基本数据类型转换器

通过基本数据类型转换器能够完成字符串和基础数据类型之间的转换,其中基础数据类型包括boolean、char、byte、short、int、long、float和double八种。

4.基本数据类型的封装类转换器

Struts2的内置转换器不但能转换基本数据类型,还能够转换基本数据类型的封装类,包括Boolean、Character、Byte、Short、Integer、Long、Float和Double八种。

5.数组类型转换器

Struts2还提供了一个数组类型的转换器,这个转换器非常常用,比如多个表单元素的name属性相同,那么提交的参数就不再是字符串而是一个字符串数组。通过Sturts 2提供的数组类型的转换器就能很方便的将多个相同name属性的表单元素的值封装到Action中的一个数组中。

6.集合类型转换器

上面介绍的是通过数组来接受参数值,同样也可以通过集合类型来接受参数值。Struts2提供的集合类型转换器,会将参数值自动添加到集合类型属性中。

7.日期类型转换器

通过日期类型转换器能够自动完成字符串类型与日期类型之间的转换。不过字符串类型必须符合日期格式规范,否则将类型转换错误。

自定义类型转换器

1.实现自定义类型转换器

前面介绍的都是Sturts 2内建的类型转换器,下面来看如何创建自定义的类型转换器。假如现在有一个自定义的类Point类,包括x和y两个属性,分别代表x坐标值和y坐标值。那么如果通过表单的参数值来设置Point类的属性呢,这时就必须通过自定义类型转换器来完成。

Struts2的类型转换器是基于OGNL实现的。首先在导入的ognl-3.0.6.jar类库中找到TypeConverter类,代码如下所示。

public interface TypeConverter
{
public Object convertValue(Map context, Object target, Member member,
String propertyName, Object value, Class toType);
}

2.使用Struts2提供的StrutsTypeConverter

前面介绍了TypeConverter接口以及实现TypeConverter接口的DefaultTypeConverter类。但是我们发现通过继承DefaultTypeConverter类来实现自定义类型转换器比较麻烦。

其实Struts2提供了一个StrutsTypeConverter的抽象类,开发时可以通过继承这个类来构建类型转换器。这样可以不用对转换的类型进行判断,从而节省大量的代码和开发时间。

3.注册局部类型转换器

局部类型转换器和全局类型转换器的区别在于其作用域不同,局部类型转换器只能对指定的属性进行类型转换,全局类型转换器能够对所有指定类型的属性进行类型转换。

注册局部类型转换器非常简单,只需要在相应的Action目录下新建一个资源文件。该资源文件名格式如下。

ActionName-conversion.properties

其中ActionName表示需要进行转换的Action的类名,“-conversion.properties”字符串则是固定格式的。该文件是一个典型的资源文件,文件内容由键值对组成,格式如下所示。

propertyName= ConverterName

其中propertyName用来指定需要进行类型转换的属性,ConverterName用来指定自定义类型转换器的类名。

4.注册全局类型转换器

Sturts 2中还提供了一种注册全局类型转换器的方式。通过这种方式可以不必重复指定Action中的属性以及对应的转换器类。即使系统中多个Action都包含了Point类型的属性,也可以通过定义全局类型器来一次实现,而无需多次注册。

要实现全局类型转换器,必须提供一个xwork-conversion.properties文件,该文件必须保存在classes目录下。该资源文件名格式如下。

ClassName= ConverterName

其中ClassName用来指定需要进行类型转换的类,ConverterName用来指定自定义类型转换器的类名。如果注册了全局类型转换器,那么对于所有的ClassName类型属性都能起作用。

5.类型转换执行流程

为了更好的理解Struts2类型转换的机制,下面我们来看类型转换的执行流程。首先来看字符串转换为自定义类型的执行流程,其执行流程图如图所示。

6.类型转换中错误处理

前面我们在输入各种转换信息时,都是按照格式来进行输入的。假如不按照格式来进行输入,类型转换就会失败,比如在年龄的字段中输入一个“ss”字符串,或者在日期的字段中输入一个“abcs”的字符串。

那我们该如何处理类型转换中的错误呢?最好的方式就是提示错误信息,要求用户重新输入符合格式的信息。要添加错误信息需要进行如下两个步骤。

1.在struts.xml中配置类型转换失败后的跳转页面,代码如下所示。

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

2.在输入页面中添加错误提示信息输出代码,代码如下所示。

<s:fielderror name="point"/>

经过前面两个步骤,就可以输出类型转换的错误信息了。

7.输出指定的错误信息

在上一节的内容中实现了错误信息的输出,但是这样的错误信息对于一般的用户来说是非常糟糕的。那我们可以修改这些错误提示信息吗?答案是可以的,可以通过国际化资源文件来实现自定义的转换错误信息,步骤如下。

1.在struts.xml文件中配置一个struts.custom.i18n.resources常量,并指定国际化资源文件的文件名,代码如下所示。

<constant name="struts.custom.i18n.resources" value="messageResource"></constant>

2.添加国际化资源文件,国际化资源文件一般有多个,每个国家区域都有不同的国际化资源文件。在这里添加一个中文的资源文件messageResource_zh_CN.properties,代码如下。

xwork.default.invalid.fieldvalue ={0}字段类型转换失败

Struts2输入校验

1.输入校验的重要性

输入校验分为客户端校验和服务器端校验。客户端校验用来过滤用户的错误操作,一般使用JavaScript代码实现。服务器端校验用来防止非法用户的恶意输入,使用Java代码实现。

仅有客户端验证还是不够的,攻击者可以直接将整个输入页面下载下来,然后通过删除相应的JavaScript代码,然后再提交表单。这样的话,就算是输入不合法的信息,客户端校验也起不了作用。通过一种如此简单的方法就可以绕过这些JavaScript校验代码。那些侵入者很可能使用更加高级的手段来绕过这些JavaScript代码,从而直接提交非法的数据。要避免这种情况就必须添加服务器端校验。

服务端校验是整个Web应用中最重要的一道防线。用户是无法直接接触到服务器端代码的,这样的话就算是客户端校验被人绕过,仍然能够通过服务器端校验来阻止用户的非法输入。服务器端校验对于系统的安全性、完整性、健壮性起到了至关重要的作用。

2.通过实现validate方法完成输入校验

ActionSupport类中定义了一个validate方法,通过实现该方法可以用来完成输入校验。下面来看一个简单的范例,通过判断用户输入的年龄是否在0到100之间,如果不是则提示错误信息,如果是则跳转到显示页面显示用户年龄信息。

3.保存表单提交信息

从前面的范例中我们发现,如果输入了非法信息,在页面跳转回表单输入页面时以前提交的数据不存在了。下面来看如何保存表单提交信息,有两种方法可以实现,第一种是通过在表单的每个字段中添加value属性,并设置值;第二种是通过使用Struts2的表单标签来实现。

4.使用addFieldError添加错误信息

前面介绍的都是通过addActionError方法添加错误信息,Struts2还提供了另一种添加错误信息的方式,那就是addFieldError方法。

ActionError本身是一个ArrayList实例对象,将错误信息保存在ActionError中,其实就是保存在一个ArrayList中。FieldError和actionError不同,其采用Map结构来存储的,所以都是以键值对来保存信息,其中键用来保存发生错误的字段名称,值用来保存具体的错误信息。

5.Struts2输入校验流程

为了更形象和深入的了解输入校验,

下面我们一起来看输入校验的流程,

其输入校验的程序流程图如图所示。

Struts2校验框架

1.使用校验框架的好处

在前面介绍了通过实现validate方法来完成输入校验,但是我们发现实现起来需要编写大量的代码,而且这样的校验代码很难实现重用。在实际的开发中将有大量的表单需要处理,这样的校验方式需要耗费大量的开发时间。

这时我们可以使用Struts2提供的校验框架,通过该校验框架可以非常简单和快速的完成输入校验。这个校验框架的核心是一个XML文件,通常被称为校验规则文件。通过在该文件中配置校验规则从而实现输入校验。

2.编写校验规则文件

校验规则文件是一个典型的XML文件,其文件名格式为ActionName-validation.xml。其中ActionName为对应处理Action的类名,-validation.xml为固定格式。该文件存放在Action文件的相同目录下。

创建完校验规则文件后,需要在该文件中添加XML规范、DTD以及根目录信息,代码如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
</validators>

3.校验器配置风格

Struts2提供了两种方式来配置校验器:字段校验器配置风格和非字段校验器配置风格。这两种配置风格并没有本质上的区别,只是组织校验规则文件的方式不同。

validators元素下可以出现两个元素field和validator,使用这两个元素有什么不同呢?如果使用field元素就是字段优先,表示使用字段校验器配置风格;如果使用validator元素就是校验器优先,就是非字段校验器配置风格。

4.内建校验器注册文件

Struts2提供了非常多的默认校验器。在开发中使用内建的校验器能满足大部分的校验需求。对于这些内建的校验器,只需知道校验器名称以及参数就能实现对应的校验功能,对于底层的校验细节则可以不用了解。下面来看Struts2到底提供了哪些内建的校验器。

首先找到导入的库文件xwork-core-2.3.24.jar。依次展开其中的com\opensymphony\xwork2\validator\validators目录。在validators目录下可以找到一个名为default.xml的文件,该文件为Struts2的内建校验器注册文件,在该文件中注册了Struts2中所有的内建校验器。

5.常用的内建校验器

Struts2内建的校验器非常多,下面来介绍几个常用的,如必填校验器、整数校验器、日期校验器、邮箱地址校验器以及字符串长度校验器。

1.必填校验器

必填校验器的名称为required,其用来校验指定的字段是否非空。

2.整数校验器

整数校验器的名称为int,可以用来校验字段的整数值是否在指定范围中。

3.日期校验器

日期校验器的名称为date,可以用来校验字段的日期值必须在指定范围中。

4.邮箱地址校验器

邮箱地址校验器的名称为email,用来校验字段是否是一个合法的邮箱地址。

5.字符串长度校验器

字符串长度校验器的名称为stringlength,用来校验指定的字段字符串长度是否在指定的范围中。

Struts2拦截器

拦截器是Struts2的核心组成部分,Struts2的大部分功能都是通过拦截器来完成的。Struts2通过一种可插拔式的设计来添加或删除使用拦截器,从而提供了非常好的可扩展性。通过Struts2提供的内建拦截器可以完成许多的功能,同时开发人员还可以自定义拦截器从而扩展Struts2框架。

重点内容:

拦截器实现原理

自定义拦截器

配置拦截器

为拦截器传入参数

拦截器介绍以及实现原理

1.拦截器简介

那到底什么是拦截器呢?下面通过一个现实生活的例子来说明,假如现在你乘电梯去办公室。在你进入电梯之前,电梯要首先开门你才能进入。同样当你进入电梯后,电梯将自动关门。这时电梯就可以看作是一个拦截器,在你进去之前和之后都进行了操作,其示意图如图所示。

拦截器的功能,就是在进行一个

操作(调用方法)时,它会在用户执

行操作前进行一系列操作,同样在用

户操作完成后,进行一系列操作。

2.拦截器实现原理

这里发现了一个问题,电梯应该是自动开门和自动关门的,也是就拦截器中的方法应该是自动执行的。

有读者肯定有疑问,方法可以在不调用的情况下自动执行吗?其实这里所指的自动执行不是说真正的自动,而是指通过代码驱动来由系统自动执行,这时需要用到动态代理方面的知识。其实所谓的拦截其实就是动态的生成一个代理对象,而在这个代理对象中包含了拦截器方法的调用。所以当调用该代理对象的方法时,同时会调用拦截器中的方法,通过这样的方法就实现了动态调用拦截器方法的目的。

自定义拦截器

1.通过Interceptor接口实现拦截器

前面介绍了动态代理模式以及拦截器实现原理,现在开始本章的重头戏自定义拦截器。首先来看如何定义自己的拦截器。

打开com.opensymphony.xwork2.ActionInvocation包,找到并打开Interceptor.java文件,代码如下所示。

public interface Interceptor extends Serializable {
void destroy() //销毁方法
void init(); //初始化方法
String intercept(ActionInvocation invocation) throws Exception; //拦截方法
}

2.通过AbstractInterceptor类实现拦截器

前面通过实现Interceptor接口实现了自定义拦截器类的,但是我们发现就算我们不需要对拦截器的初始化和销毁进行任何操作,也不得不实现init方法和destroy方法。

这时可以使用另外一个类AbstractInterceptor。该类是一个抽象类并实现了Interceptor接口,其代码如下所示。

public abstract class AbstractInterceptor implements Interceptor {
public void init() {//初始化方法}
public void destroy() {//销毁方法}
public abstract String intercept(ActionInvocation invocation) throws Exception; //拦截方法
}

3.截器配置拦截器

前面介绍了如何定义拦截器类,但是这时拦截器还不能起作用。要拦截器其作用则必须在struts.xml文件中配置该拦截器,下面介绍几种配置拦截器的方法。

1.最简单的配置

2.配置并传递参数

3.配置多个拦截器

4.配置拦截器栈

5.配置拦截器栈并传递参数

6.在拦截器栈中再引入拦截器栈

4.使用拦截器

前面已经介绍了如何配置拦截器,但是现在拦截器还是不能起作用。因为Action还不知道要使用哪个拦截器,所以还必须在Action元素中通过添加interceptor-ref节点来指定使用哪个拦截器,代码格式如下所示。

<action name="业务控制器名" class="业务控制器实现类">
<result name="success"></result>
<interceptor-ref name="拦截器名"></interceptor-ref>
</action>

interceptor-ref节点中包含一个属性name,该属性用来配置需要使用的拦截器的名称。

5.使用默认拦截器

Struts2中的类型转换、输入校验、文件上传等操作都是通过调用特别的拦截器来完成的,拦截器是Struts2的核心部分。但是在struts.xml文件中我们并没有使用这些拦截器,这些拦截器是如何起作用呢?

这是因为在配置Action时,将该Action放到了Struts2包中,而这个包继承了struts-default。重点在于在struts-default中配置了默认的拦截器栈defaultStack,在该拦截器栈中定义了大量的拦截器。struts2这个包继承struts-default,就相当于同样配置了默认的拦截器栈defaultStack,所以可以不用手动配置和使用这些拦截器。

只需要在使用myInterceptor拦截器后添加一个interceptor-ref,并指定其name属性为defaultStack,就可以使用默认拦截器栈中的拦截器了。

深入拦截器

1.为拦截器传入参数

可以通过两种方式为拦截器传入参数,一种是通过在配置拦截器时配置参数,一种是在使用拦截器是为其配置参数。

要为拦截器传入参数,拦截器就必须能接受参数。下面来定义一个拦截器,能够接受参数,并对参数进行处理。

public class MyInterceptor3 extends AbstractInterceptor{
private String interceptorName; public void setInterceptorName(String interceptorName) { this.interceptorName = interceptorName;
}
}

2.配置拦截器栈

前面介绍了配置拦截器栈的语法,下面我们来看如何将MyInterceptor2和MyInterceptor3两个拦截器配置成拦截器栈。

<interceptor name="myInterceptor2"
class="com.tufujie.interceptor.MyInterceptor2"></interceptor>
<interceptor name="myInterceptor3"
class="com.tufujie.interceptor.MyInterceptor3">
<param name="interceptorName">自定义拦截器</param>
</interceptor>
<interceptor-stack name="myInterceptorStack">
<interceptor-ref name="myInterceptor2"></interceptor-ref>
<interceptor-ref name="myInterceptor3"></interceptor-ref>
</interceptor-stack>

3.覆盖拦截器栈中指定拦截器的参数

前面介绍了在使用拦截器时也可以为拦截器指定参数。同样在使用拦截器栈时也可以为每个拦截器指定参数,从而覆盖在配置拦截器时指定的参数值。

修改action节点下的interceptor-ref节点,通过添加param节点来添加参数,并指定参数名和参数值,代码如下所示。

<action name="register" class="com.tufujie.action.RegisterAction">
<result name="success">/ShowUserInfo.jsp</result>
<result name="input">/Register.jsp</result>
<interceptor-ref name="myInterceptorStack">
<param name="interceptorName">使用拦截器栈</param>
</interceptor-ref>
</action>

4.拦截器执行顺序

拦截器的执行顺序是理解整个拦截器体系中最重要的部分,拦截器执行顺序规则如下所示。

(1)在拦截器中先引入的拦截器会

先执行,后引入的拦截器会后执行。

(2)一个拦截器执行完成其拦截前

操作后,会传递给下一个拦截器(如

果有多个拦截器的话)或者Action。

(3)当一个拦截器的执行完成后,

会返回其上一个拦截器,继续执行

上一个拦截器的拦截后操作。

根据第2点和第3点规则绘制拦截器

执行的流程图,如图所示。

Struts2内建拦截器

1.内建拦截器介绍

Sturts 2内建了大量的拦截器,并配置在struts2-core-2.1.6.jar类库中的struts.xml文件中。从该文件中可以看到Struts2中所有内建的拦截器。

大家可能会觉得这么多的拦截器,要完全了解是件非常困难的事情。其实不然这些拦截器平常可以不用去深究,只有在需要使用的时候通过研究其源代码或者Struts2的参考文档就能很快上手了。平常在使用的时候,一般都会选择继承struts-default包,这样就可以使用到Struts2的大部分拦截器了。

2.内建拦截器的配置

从struts.xml文件中可以看到,在该文件中为内建的拦截器配置了许多的拦截器栈,代码如下所示。

<interceptor-stack name="basicStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
</interceptor-stack>

Struts2标签库

Struts2同Struts1一样,为页面开发提供了大量的标签,但是相比而言Struts2的标签库更加强大。首先Struts2的标签库中整合了Dojo技术,能够生成大量的页面效果。同时Struts2提供了许多Struts1中没有的标签,如日期选择器、树状结构、主体模板等等。借助于Struts2标签来开发页面可以使得页面更加整洁并且容易维护,同样可以减少代码量以及开发时间。

重点内容:

Struts2标签库的组成和使用

使用控制标签

使用数据标签

使用表单标签

使用Ajax标签

Struts2标签库概述

1.Struts2标签库的组成

Struts2提供的标签非

常多,其大致分为两类,一

类是用户界面标签,也称为

UI标签;一类是非用户界面

标签,也称为非UI标签。

其中非UI标签主要用于

数据访问和逻辑控制,按其

功能将其分为两类:一类是

数据标签,一类是控制标签

。下表中列出了所有的非UI

标签以及其功能。

其中UI标签主要用来生成HTML元素,按其功能将其分为三类。一类是表单标签,一类是非表单标签,另一类是AJAX标签。下表中列出了所有的UI标签以及其功能。

2.Struts2标签库的使用

Struts2的标签库都被定义在了struts-tags.tld这个文件中,读者可以在struts2-core-2.1.6.jar库文件的META-INF目录中找到它。Struts2标签的使用随Web容器版本的差异而不同。

如果使用Web容器支持的是Servlet 2.4及其以上的规范,则无需在web.xml文件中添加taglib,因为Web应用会自动读取该TLD文件信息。

要使用Struts2的标签还必须在JSP页面中使用taglib指令来导入Struts2的标签,引入代码如下所示。

<%@ taglib prefix="s" uri="/struts-tags" %>

通过上面的配置就可以在JSP页面中使用Struts2提供的标签了。

控制标签

1.if/elseif/else标签

if/elseif/else是三个标签的组合,这三个标签都用于进行条件逻辑控制。其中if标签、elseif标签中提供了一个test属性用来进行判断,该属性返回一个布尔值。通过判断该布尔值来决定是否执行标签体的内容。只有当if、elseif标签的test属性都返回false时,才执行else标签的标签体内容。if/elseif/else标签的使用和Java语言中的if-elseif-else条件逻辑控制语言使用上是基本类似的。

2.iterator标签

iterator标签用来对集合进行遍历,这里所指的集合包括数组、List、Set以及Map对象。iterator标签中有三个属性,如下表所示。

iterator标签一般用来遍历Action类的集合属性,这里为了示例的演示方便,将在JSP页面中创建该集合用来模拟从Action获得的集合。可以使用OGNL表达式中的“{e1,e2,e3…..}”来生成一个List类型集合。

3.append标签

append标签用于将多个集合拼接组合成一个新集合,该标签仅仅包含一个id属性,该属性用来指定新集合的名字。在append标签中可以指定多个param子标签,每一个param标签指定一个需要被组合的集合。

4.merge标签

merge标签同append标签类似,都是用来将多个集合组合成一个新集合。两个都有一个id属性,用来设置新集合的名称,这两个标签的不同点在于组合集合的方式。append标签采用追加的形式,也就是说先组合完成一个集合中的所有元素,再组合下一个集合中的所有元素,集合和集合是首尾相接的。

5.generator标签

generator标签用来将制定的字符串按照指定分隔符分隔成多个子字符串,并将这些子字符串放置到一个集合对象中。转换后的集合对象可以使用iterator标签来迭代输出。generator标签包含五个属性,如下表所示。

6.subset标签

subset标签用来取得集合的子集,其属性说明如下表所示。

7.sort标签

sort标签用来对指定的集合中元素进行排序,sort标签并没有提供自己的排序规则,而是由开发人员提供排序规则。排序规则就是一个实现java.util.Comparator接口的类。sort标签的属性说明如下表所示。

数据标签

1.action标签

action标签允许在JSP中直接访问并调用Action,还可以通过executeResult属性选择是否将处理结果包含在当前页面中。Action

标签包含属性如下表所示。

2.bean标签

bean标签允许直接在JSP页面中创建JavaBean实例。在创建Java Bean对象时,如果需要设置JavaBean的属性,可以在标签体内使用param标签传递参数。bean标签属性如下表所示。

3.date标签

date标签用来格式化输出指定的日期或者时间,除此之外,date标签还可以输出指定日期到当前时刻的时间差。data标签属性如下表所示。

4.debug标签

debug标签可以用来输出服务器端对象中的信息,比如request范围的属性,session范围属性等等。debug标签可以用来辅助开发人员调试Web程序,方便开发人员查看服务器各类信息。在使用debug标签后,网页中会生成一个“[Debug]”的链接,单击该链接,页面将会输出各种服务端对象中信息。

5.include标签

include标签用来在当前页面中包含另一个JSP页面,或者Servle t。include标签属性如下表所示。

6.param标签

param标签主要用来为其他标签提供参数,比如append、bean、merge等标签。param标签属性如下表所示。

7.property标签

property标签用来输出指定值,输出的值通过value属性来指定,如果不指定该属性,则默认输出ValueStack栈顶的值。property标签属性如下表所示。

8.push标签

push标签用来将指定值设置到ValueStack的栈顶,设置完成后,可以很方便的访问该值。property标签属性如下表所示。

9.set标签

set标签用于将值保存到指定属性范围,等同于JSP中的等同于setAttribute()方法。其包含属性如下表所示。

10.url标签

url标签用来生成一个URL地址,可以通过在其标签体中添加param标签传递请求参数。url标签包含属性如下表所示。

表单标签

1.简单表单标签

下面来看一组简单表单标签,这些标签都可以HTML中找到其相应的标签,标签列表如下表所示。

2.checkboxlist标签

checkboxlist标签用来生成复选框组,该复选框组包含多个复选框。也就是说,通过checkboxlist标签可以生成一系列HTML中的<input type="checkbox"> 标签。checkboxlist标签常用属性如下表所示。

3.combobox标签

combobox标签用来生成一个单行文本框和下拉列表框的组合,而且这两个元素对应一个相同参数。其中以当行文本框中的值作为其请求参数的值,而下拉列表框只是起到一个辅助输入的作用。combobox标签包括的常用属性如下表所示。

4.datetimepicker标签

datetimepicker标签用来生成一个文本框和日期、时间选择器的组合,在选择器中选择完某个日期或者时间时,会自动将被选择的日期或者时间输入文本框中。datetimepicker标签包括的常用属性如下表所示。

5.doubleselect标签

doubleselect标签用来生成一个级联下拉列表框,该列表框由两个列表框组成,当设置一个列表框的选项时,另一个列表框中的选项会随之变化。doubleselect标签包括的常用属性如下表所示。

Struts个人总结的更多相关文章

  1. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  2. Struts的拦截器

    Struts的拦截器 1.什么是拦截器 Struts的拦截器和Servlet过滤器类似,在执行Action的execute方法之前,Struts会首先执行Struts.xml中引用的拦截器,在执行完所 ...

  3. Struts框架的核心业务

    Struts的核心业务 Struts核心业务有很多,这里主要介绍了比较简单一些的: 请求数据的处理,和数据自动封装,类型自动转换 1.Struts中数据处理 1.1.方式1:直接过去servletap ...

  4. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  5. 配置hibernate,Struts。文件

    hibernate文件配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernat ...

  6. hibernate与Struts框架结合编写简单针对修改练习

    失败页面fail.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  7. 3. 解析 struts.xml 文件

    1. struts.xml 文件基本配置: 主要放在资源路径下,配置 sturts2相关的 Action , 拦截器等配置 <struts> <!-- 设置常量 --> < ...

  8. Struts+Spring+Hibernate项目的启动线程

    在Java Web项目中,经常要在项目开始运行时启动一个线程,每隔一定的时间就运行一定的代码,比如扫描数据库的变化等等.要实现这个功能,可以现在web.xml文件中定义一个Listener,然后在这个 ...

  9. Struts 原理

    今天开始接触公司的框架,叫YNA,三个字母应该是雅马哈的缩写,这个框架听公司前辈说功能很强大,但实际上我看不懂.哈哈...... 其中整合了SSH框架,接下来我说下Struts的一些原理 其实这张图就 ...

  10. axis2+struts拦截地址冲突问题

    axis2和struts在整合过程中,struts会把axis的地址也拦截了,默认当成一个action处理, 会因为找不到action而报错: <!-- struts配置 --> < ...

随机推荐

  1. JavaScript异步获取数据解析

    <script type="text/javascript">    var xhr=false;    function createXhr() {    var x ...

  2. Redis 与 数据库处理数据的两种模式(转)

    Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了Pyt ...

  3. HTML5 + SOCKET视频传输

    <html> <head> <meta http-equiv="content-type" content="text/html; char ...

  4. 非关系型数据库SequoiaDB虚拟机下应用初探

    SequoiaDB是广州巨杉软件有限公司开发的一款新型分布式非关系型数据库.可应用于linux操作系统下.在虚拟机下试用了一下(操作系统Ubuntu),感觉不错,操控简单易上手,在此分享一下心得. 下 ...

  5. 运用百度开放平台接口根据ip地址获取位置

    使用百度开放平台接口根据ip地址获取位置 今天无意间发现在百度开放平台接口,就把一段代码拿了下来,有需要的可以试试看:http://opendata.baidu.com/api.php?query=5 ...

  6. aliexpress 上传图

    首先,图片转化为字节流 public byte[] ImagefileToByte(string srcImagePath) { System.IO.MemoryStream m = new Syst ...

  7. C# 学习之旅(1)

    第一, 输入输出流都来自控制台. using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  8. SQL Server是如何让定时作业

    如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理->SQL Server代理->作业来实现. 1.管理->SQL S ...

  9. 父子进程间通信模型实现(popen)

    0.FILE *popen(const char *command, const char *type); popen 函数相当于做了以下几件事: 1.创建一个无名管道文件 2. fork() 3.在 ...

  10. Hibernate从入门到精通(二)Hibernate实例演示

    上篇Hibernate从入门到精通(一)JDBC简介,我们主要对JDBC进行了简单介绍和使用说明,这次我们做一个Hibernate简单实例,通过这个实例对比Hibernate和JDBC,了解Hiber ...