Java Web学习笔记——Struts2入门

Java学习笔记——Struts2入门

一、Struts2的概念

        Struts是Apache基金组织中一个开源项目,主要实现MVC设计模式,在Struts中有自己的控制器(ActionServlet),同时也提供了各种常用的页面标签库以减少JSP页面中的Scriptlet代码。

Java Web学习笔记——Struts2入门

Struts是流程和成熟的基于MVC设计模式的Web应用程序框架。

二、MVC模式
        MVC是模型视图控制器(Model View Controller),一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

Java Web学习笔记——Struts2入门


三、Struts2的发展历史

        Struts2不是一个全新的框架,因此稳定性、性能等方面都有很好的保证,同时吸收了Struts1和WebWork两者的优势。

Java Web学习笔记——Struts2入门

四、第一个Struts2例子

1.Apache Struts2的环境需求如下:

    Servlet API 2.4

    JSP API 2.0

    Java 5

注意,在Struts2中用到Annotation,所以需要将JDK版本升级到1.5以上。


2.搭建Struts2环境步骤:

    (1)下载相关的Jar包(http://struts.apache.org/)

    (2)创建Web项目

    (3)创建并完善相关配置文件

    (4)创建Action并测试启动


五、Struts2的工作原理及文件结构

Java Web学习笔记——Struts2入门


从Struts 2.1.3开始,StrutsPrePareAndExecuteFilter替代FilterDispatcher

一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码:https://github.com/apache/struts):
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 
3 接着FilterDispatcher(现已过时)被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action 
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy 
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类 
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper


在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的

核心文件介绍:

1. web.xml

    任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只有配置在web.xml文件中Servlet才会被应用加载。

    通常,所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts2框架而言,需要加载StrutsPrepareAndExecuteFilter,只要Web应用负责加载StrutsPrepareAndExecuteFilterStrutsPrepareAndExecuteFilter将会加载Struts2框架。

    因为Struts2将核心控制器设计成Filter,而不是一个普通Servlet。故为了让Servlet。故为了让Web应用加载StrutsPrepareAndExecuteFilter,只需要在web.xml文件中配置StrutsPrepareAndExecuteFilter即可。

2. struts.xml

struts2的核心配置文件,主要负责管理应用中的Action映射,以及该Action包含的Result定义等。

struts.xml中包含的内容:

    1)全局属性

    2)用户请求和响应Action之间的对应关系

    3)Action可能用到的参数和返回结果

    4)各种拦截器的配置

3. struts.properties

    struts2框架的全局属性文件,自动加载。该文件包含很多key-value对。

    该文件完全可以配置在struts.xml文件中,使用constant元素

struts.xml中的标签及说明:

        include节点是struts2中组件化的方式,可以将每个功能模块独立到一个xml配置文件中,然后用include节点引用这些xml配置文件。

        package提供了将多个Action组织为一个模块的方式,package的名字必须是唯一的,package可以扩展,当一个package扩展自另一个package时,该package会在本身配置的基础上加入扩展的package的配置,父package必须在子package前配置

            name:package名称

            extends:继承的父package名称

            abstract:设置package的属性为抽象的,抽象的package不能定义action,值true:false

            namespace:定义package命名空间,该命名空间影响到url的地址,例如此命名空间为/test,那么访问的地址为http://localhost:8088/struts2/test/xx.action

        interceptors拦截器节点,name拦截器名称,class拦截器类路径。

        定义默认的拦截器default-interceptor-ref,每个Action都会自动引用,如果Action中引用了其他的拦截器,默认的拦截器将无效。

        全局results配置global-results

        Action配置:一个Action可以被多次映射(只要action配置中的name不同),name:action名称,class:对应的类的路径,method:调用Action中的方法名。

struts.propertires常用设置项:

        struts.i18n.encoding = GB2312

        #指定默认编码集,对于请求参数带有中文的情况应该设置成GBK或GB2312,默认值UTF-8

        struts.i18n.reload = true

        #是否每次HTTP请求到达时,都重新加载国际化资源文件,默认值false

        struts.configuration.xml.reload = true

        #但struts.xml改动后,是否重新加载该文件。在开发阶段建议将次属性设置为“true”,提高开发效率,默认值false

        struts.devMode = true

        #是否使用Struts2的开发模式,可以获得更多报错信息,便于调试,在开发阶段设置true,默认值false

        struts.serve.static.browerCache=true

        #指定浏览器是否缓存静态页面,开发阶段设置false,以获得服务器的最新响应。默认值true

        struts.action.extension = action,do,struts2,

        #指定后缀为.action形式的请求可被Struts2处理,可配置多个请求后缀,比如.do、.struts2等,配置时多个后缀名用逗号隔开

        struts.url.http。port= 8080

        #配置服务器运行时的端口号,一般情况下该属性不修改,如果端口号占用则重新分配端口号,默认值80

        

六、深入理解Struts2的用法

1.访问Servlet API

Java Web学习笔记——Struts2入门

Struts2提供了三种方式访问Servlet API:

1) ActionContext

2) 实现***Aware接口

3) ServletActionContext

2. Action搜索顺序

http://localhost:8080/struts2/path1/path2/path3/student.action

第一步:判断package是否存在,如:path1/path2/path3/

如果package存在:

第二步:判断action是否存在,如果不存在,则取默认namespace的package里面寻找action

第三步:如果没有,则报错

如果package不存在;

第二步:检查上一级路径的package是否存在(直到默认namespace),重复第一步

第三步:如果没有,则报错

3.动态方法调用

为了解决一个Action对应多个请求的处理,以免Action太多:

1)指定method属性

Java Web学习笔记——Struts2入门

2)感叹号方式

需要在struts.xml中配置常量值

Java Web学习笔记——Struts2入门

http://localhost:8080/HelloWorld/helloworld!add.action

http://localhost:8080/HelloWorld/helloworld!update.action

Java Web学习笔记——Struts2入门

3)通配符方式

建议使用的方式

Java Web学习笔记——Struts2入门

通过使用*号和下划线_匹配Action,使用数字{1}表示第一个字段,{2}匹配第二个字段,如果存在包名,则可以通过三个星号*,并用下划线连接。Java Web学习笔记——Struts2入门,{3}匹配的是包名,这样就可以在struts.xml只写一个action。

4.指定多个配置文件

使用include包含标签

<include file = "login.xml"></include>

<include file = "system.xml"></include>

Java Web学习笔记——Struts2入门

配置文件的字符编码统一:

<constant name = "struts.i18n.encoding" value="UTF-8></constant>

5. 默认Action

出现找不到Action时,默认Action就可以进行顶替。

Java Web学习笔记——Struts2入门

6. Struts2后缀

在struts.xml中增加一个常量

Java Web学习笔记——Struts2入门

当不设置该参数时,使用.action后缀和不使用后缀均可正常显示

另外,在struts.properties中也可以配置该常量

Java Web学习笔记——Struts2入门

还可以在web.xml的过滤器中配置初始化参数

Java Web学习笔记——Struts2入门

7. 接收参数

1)使用Action的属性接收参数

Java Web学习笔记——Struts2入门

在配置文件中添加action标签:

Java Web学习笔记——Struts2入门

创建对应的jsp页面

创建Action类,继承ActionSupport,定义属性,实现get和set方法

当有较多的输入的时候,可以考虑第二种方式

2)使用Domain Model接收参数

创建一个对象的类,然后在Action类中声明一个对象,不需要实例化

3)使用ModelDriven接收参数(推荐使用)

实现ModelDriven接口

Java Web学习笔记——Struts2入门

这时可以去掉get和set方法,并进行对象的实例化

另外通过request的方式也是可以的

8. 处理结果类型

Struts2处理流程

Java Web学习笔记——Struts2入门

Struts2处理结果是字符串,有利于代码复用性和框架分离

<result name = "success">/success.jsp</result>

result元素中name就是result元素的逻辑视图名称。

<result>/success.jsp</result>与上述语句是一样的,如果省略了name属性,系统将采用默认的name属性,默认的name值是success,但是success是系统内置的。

有5个系统内置的action属性,继承自com.opensymphony.xwork2.Action

1)SUCCESS——Action正确的执行完成,返回相应的视图,success是name属性的默认值;

2)NONE——表示Action正确的执行完成,但并不返回任何视图

3)ERROR——表示Action执行失败,返回到错误处理视图

4)LOGIN——Action因为用户没有登录的原因没有正确执行,将返回该登录视图,要求用户进行登录验证

5)INPUT——Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果验证没有通过,将自动返回该视图。

但是,需要明确的是,这些常量名称只是帮助我们理解,常量背后的路径需要我们自己设定

 

处理结果是通过在struts.xml使用<result/>标签配置结果。

根据位置的不同,分为两种结果:

    1)局部结果:将<result/>作为<action/>元素的子元素配置

    2)全局结果:将<result/>作为<global-result/>元素的子元素配置,global-result必须在一个包下面实现

<result name="......">

    <param name = "location">resource</param>

</result>

子标签<param>具有两个属性:

1)location:该属性定义了该视图对应的实际视图资源。

2)parse:该参数指定是否可以在实际视图名字中使用OGNL表达式

strut2框架默认该属性为true,即支持OGNL表达式

OGNL:Object-Graph Navigation Language


<result name = "success" type=" ">/success.jsp</result>

type的默认值为dispatcher,这个类型支持JSP视图技术

struts2支持多种视图技术,例如JSP、Valocity、FreeMarker等

在struts.default.xml中,有

Java Web学习笔记——Struts2入门

其中的,chain:将action和另外一个action链接起来;redirect:重定向会丢失请求参数;plainText:用于显示界面的源代码

七、关于struts1的补充内容

struts开发框架有如下的优点:

(1)所有的错误信息都是通过ApplicationResource.properties文件进行配置的,所以当需要更换错误信息时直接修改资源文件即可。

(2)所有的跳转路径都是通过struts-config.xml进行配置的,以后通过此文件可以直接改变跳转路径。

(3)在struts中专门提供了用于输入验证的操作类ActionForm,这样Action可以专注于业务的处理。

Strutsd的完整工作流程:

(1)在web.xml中为ActionServlet配置一个映射路径,一般都为*.do。

(2)当一个JSP页面执行是,如果使用的是HTML标签定义的表单,则会根据action指定的路径与strut-config.xml文件中的路径相匹配,如果匹配失败,则程序会报错。

(3)在运行一个JSP页面前,会调用指定ActionForm中的reset()方法,进行表单的初始化操作。

(4)用户提交表单时会将所有的操作都提交的ActionServlet(由*.do指定)中,之后由ActionServlet根据struts-config.xml文件中的配置调用指定的ActionForm和Action进行处理。

(5)表单提交的数据首先会交给ActionForm处理,并自动调用其中的validate()方法进行验证,如果验证成功(validate()方法返回null或者ActionErrors中没有任何内容),则交给响应的Action进行处理;如果验证失败,则跳转到提交Action中配置的input属性中指定的页面路径,此时可以通过<html:errors>标签显示所有的错误信息。

(6)Action负责完成具体的业务操作,并根据操作的结果通过ActionMapping进行跳转,ActionMapping的findForward()方法返回一个ActionForward对象以完成跳转。


Struts常用的标签库

表1:Struts标签库
No. 标签库 描述
1 Bean标签 管理JSP页面中的Bean操作
2 Logic标签 完成各种逻辑控制操作
3 Html标签 显示标签,主要是生成HTML标记
4 TILES标签 使用动态模板构造显示页面
5 NESTED 使用嵌套标签进行复杂的页面显示

这些标签在使用时直接通过<%@taglib%>指定即可

Bean标签库的主要作用是定义和访问JavaBean。有<bean:define>、<bean:size>、<bean:cookie>、<bean:header>、<bean:parameter>、<bean:write>、<bean:include>、<bean:resource>、<bean:message>,这些标签都定义在struts-bean.tld文件中。

Logic标签的主要作用是进行各种逻辑处理,如执行分支语句、迭代、比较等操作,例如<logic:present>、<logic:notPresent>、<logic:empty>、<logic:notEmpty>、<logic:equal>、<logic:notEqual>、<logic:greaterEqual>、<logic:lessEqual>、<logic:lessThan>、<logic:greaterThan>、<logic:iterate>、<logic:redirect>,这些标签都定义在struts-logic.tld文件中。

Html标签主要用于页面的显示,如<html:form>、<html:text>、<html:password>、<html:radio>、<html:hidden>、<html:submit>、<html:reset>、<html:button>、<html:checkbox>、<html:option>、<html:options>、<html:optionsCollection>,这些标签都与ActionForm紧密绑定,所有的Html标签都定义在struts-html.tld文件中。


Token:主要以一种指令牌的形式进行重复提交处理的,很多情况下,如果用户对同一个表单进行了多次提交,则可能造成数据的混乱,此时,Web服务器必须可以对这种重复提交的行为作出处理。

如果纯粹地使用基本的JSP进行开发,Token的原理就是在进入到注册页之前,先通过session设置一个属性(假设设置的属性是flag,内容是true),在用户进行用户注册时,首先判断这个session中的属性是否合法(如flag=true表示合法),如果合法,则进行正确的注册操作,操作完成后,将session的相应属性修改(如flag=false),这样用户就无法再次进行提交;如果session中的属性非法,则要进行相应的错误提示,并且不再执行注册的具体操作。

在Struts中专门提供了Token的支持,在org.apache.struts.action.Action类中提供了操作Token的方法:

表2:Token操作的相关方法
No. 方法 类型 描述
1 protected boolean isTokenValid(HttpServletRequest request) 普通 判断Token是否存在,如果存在则返回true,如果不存在则返回
2 protected void saveToken(HttpServletRequest request) 普通 设置Token
3 protected void resetToken(HttpServletRequest request) 普通 删除Token

Action深入:在Struts中的Action属于一个核心的功能操作类,但是在Struts中并不只是定义了一个普通的Action,还包含了IncludeAction、ForwardAction、DispatchAction等各种常见的Action

在Struts中通过org.apache.struts.actions.ForwardAction类可以将一个JSP页面作为一个Action进行映射,通过配置struts-config.xml文件即可。

在Struts中也为引入资源提供了一个org.apache.struts.actions.IncludeAction类,通过此Action的配置,可以将一个页面进行导入。同样此Action也需要通过配置完成。

DispatchAction类,继承Action类,并且完成分发的处理操作。分发Action的使用与普通的Action类似,仍然要被一个类所继承,并且根据要求覆写方法,唯一的不同是,此时的方法可以有多个,而且这多个方法分别表示这不同的操作。

分发Action不能编写execute()方法。如果一个类集成了DispatchAction类,则在此类中一定不能编写execute()方法。

在Struts中提供了Validator框架以完成对于输入数据的验证功能。Validator框架是随Struts一起提供的,所以要想启动验证框架,只需要在struts-fonfig.xml文件中配置即可。