Java Web学习笔记——Struts2入门
Java学习笔记——Struts2入门
一、Struts2的概念Struts是Apache基金组织中一个开源项目,主要实现MVC设计模式,在Struts中有自己的控制器(ActionServlet),同时也提供了各种常用的页面标签库以减少JSP页面中的Scriptlet代码。
Struts是流程和成熟的基于MVC设计模式的Web应用程序框架。
二、MVC模式MVC是模型视图控制器(Model View Controller),一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。三、Struts2的发展历史
Struts2不是一个全新的框架,因此稳定性、性能等方面都有很好的保证,同时吸收了Struts1和WebWork两者的优势。
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并测试启动
从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应用负责加载StrutsPrepareAndExecuteFilter,StrutsPrepareAndExecuteFilter将会加载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
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属性
2)感叹号方式
需要在struts.xml中配置常量值
http://localhost:8080/HelloWorld/helloworld!add.action
http://localhost:8080/HelloWorld/helloworld!update.action
3)通配符方式
建议使用的方式
通过使用*号和下划线_匹配Action,使用数字{1}表示第一个字段,{2}匹配第二个字段,如果存在包名,则可以通过三个星号*,并用下划线连接。
,{3}匹配的是包名,这样就可以在struts.xml只写一个action。
4.指定多个配置文件
使用include包含标签
<include file = "login.xml"></include>
<include file = "system.xml"></include>
配置文件的字符编码统一:
<constant name = "struts.i18n.encoding" value="UTF-8></constant>
5. 默认Action
出现找不到Action时,默认Action就可以进行顶替。
6. Struts2后缀
在struts.xml中增加一个常量
当不设置该参数时,使用.action后缀和不使用后缀均可正常显示
另外,在struts.properties中也可以配置该常量
还可以在web.xml的过滤器中配置初始化参数
7. 接收参数
1)使用Action的属性接收参数
在配置文件中添加action标签:
创建对应的jsp页面
创建Action类,继承ActionSupport,定义属性,实现get和set方法
当有较多的输入的时候,可以考虑第二种方式
2)使用Domain Model接收参数
创建一个对象的类,然后在Action类中声明一个对象,不需要实例化
3)使用ModelDriven接收参数(推荐使用)
实现ModelDriven接口
这时可以去掉get和set方法,并进行对象的实例化
另外通过request的方式也是可以的
8. 处理结果类型
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中,有
其中的,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文件中配置即可。