struts2详解.docx
《struts2详解.docx》由会员分享,可在线阅读,更多相关《struts2详解.docx(13页珍藏版)》请在冰豆网上搜索。
struts2详解
Struts2Node
一、struts2资源下载,struts1与struts2的区别
http:
//struts.apache.org/download.cgi最好下载最全的资源包
Struts2对Struts1区别:
在Action的实现方面:
Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
线程模型方面:
Struts1的Action工作在单例模式,一个Action的实例处理所有的请求。
Struts2的Action是一个请求对应一个实例。
没有线程安全方面的问题。
Servlet依赖方面:
Struts1的Action依赖于ServletAPI,
比如Action的execute方法的参数就包括request和response对象。
这使程序难于测试。
Struts2中的Action不再依赖于ServletAPI,有利于测试,并且实现TDD。
封装请求参数:
Struts1中强制使用ActionForm对象封装请求的参数。
Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
表达式语言方面:
Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(ObjectGraphNotationLanguage)。
绑定值到视图技术:
Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
类型转换:
Struts1中的ActionForm基本使用String类型的属性。
Struts2中使用OGNL进行转换,可以更方便的使用。
数据校验:
Struts1中支持覆盖validate方法或者使用Validator框架。
Struts2支持重写validate方法或者使用XWork的验证框架。
Action执行控制的对比:
Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的声明周期。
Struts2支持通过拦截器堆栈为每一个Action创建不同的声明周期。
二、Struts2的工作机制(执行步骤)
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求;
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过
滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:
SiteMeshPlugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某
个Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Interce
pter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。
返回结
果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。
在表示的过程中可以使用Struts2框架中继承的标签。
在这个过程中需要涉及到ActionMapper。
三、struts2环境搭建
1.创建一个webObject工程
2.将所需的jar包拷到WebRoot/WEB-INF/lib下,最基本的jar包括
3.在src目录下创建一个xml文件,命名为:
struts.xml里边基本内容包括
xmlversion="1.0"encoding="UTF-8"?
>xml文件头信息
Struts名称空间:
DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"
"http:
//struts.apache.org/dtds/struts-2.0.dtd">xmlnamespace
接下就是:
标签,在些标签体中添加
然后在package标签中添加action配置
--设置struts当前状态为开发模式,设置为true会及时部署-->
--设置是否采用动态调用方法(DMI)默认是true-->
4.web.xml中的添加的配置内容
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
四、Struts2的配置和Action的使用
1.Package和命名空间(namespace)
Package的name是给当前包的命名,跟java中的package的作用同理,namespace定义package命名空间该命名空间影响到url的地址,默认是””就是指向工程的根目录。
例:
namespace=”/user”,访问路径就应该是:
http:
//localhost:
8080/appName/user/actionName
2.Action
2.1name是给action命名,用于访问时使用,这样好定位到指定的action
2.2calss指定的是该action所映射的Action类。
2.3method指明调用class指定类的方法。
也可以不指定采用DMI的方式来动态调用方法,但在struts.xml配置说明,默认是可以使用,如果要关闭此功能将设置为false
采用DMI的访问为:
http:
//localhost:
8080/appName/user/actionName!
methodName
这种方式可以减少很action的配置,调用方法很灵活方便。
3.应用注意的path问题
使用路径时需要注意所有都是采用action的路径,而不是jsp的路径,所以最好不要使用相对路径,如果需要在页面直接跳转到指定的jsp页面时,采用到相对路径的同时在jsp页面设置这样一段内容就可以解决问题,如下:
<%Stringpath=request.getContextPath();StringbasePath=request.getScheme()+":
//"+request.getServerName()+":
"+request.getServerPort()+path+"/";%>
在head标签中添加">
否则这样的路径就会找不到页面index.jsp
4.Action中通配符的使用
在使用通配符时首先必须做好事先约定,约定什么呢?
那就是命名规范。
如下要求:
a)对jsp文件命名规范,要求统一的标准来取名,如:
b)Struts.xml里action的配置时采用通配符来处理(可以把它看成正则表达式)
/Student{1}_success.jsp
/{1}_{2}_success.jsp
这里的星号是匹配从页面上访问请求过来对应的action命名的比较,在正则中星号表示所有;而大括号1取值是对应前面的第一个星号,如果从页面上传过来的是Studentadd,这时星号就表示add,对应大括号1取值得到的也是add,同时result里对jsp的名字取值也是同理。
c)在页面上访问时,当然也就要按照前面a和b中约定的规则来进行针对性的请求喽,如下:
actions表示的是namespace,studentadd表示的是action的名称,当然b中配置的是用星号来代替了add
5.Action属性接收参数
在action类中定义好取值的属性名称如:
userName和userAge同时要有get,set方法,这时在访问时
add?
userName=aa&userAge=29">
6.采用DomainModel(域模型)接收参数(DTODataTransferObject数据传输对象)
在action类声明定义好一个模型对象类型变量privateUserModeluser;当然也要有get,set方法,这是在访问时:
add?
user.userName=aaaa&user.userAge=38">
7.采用ModelDriven(模型驱动)接收参数
这时的action需要实现一个接口ModelDriven,并且在action里不要定义该接口泛型类型变量,同时实例化,也实现此接口的方法getModel();
对MVC的理解:
V(view)视图的意思,是展示处理完结果在java中也就是jsp页面
M(Model)模型是用于接收(用户从jsp页面输入的数据)和传输数据的普通java类
C(Control)控制器它的作用时控制经过处理后的数据将要调用的视图,对应到struts中的就是action啦,在action里有存Model,还有返回的View,所以Action它控制了M和V,然后再将M和V之间的耦合度解开。
8.Struts2中参数对中文乱码处理
8.1采用POST
8.2在struts.xml中配置
internationalization
8.3
9.Struts.xml中配置的constant的相关对应的键值都是在struts2-code.jar包中的org.apache.struts2包下的配置文件default.properties里。
10.Struts2里处理返回view字符的方式(等同于原struts1中向session里存放值那样的过程),它是采用标签的方式来处理传递值的,它的源码位于META-INF下面有个struts-tags.tld的文件
10.1addFieldError
10.2debug内容,ValueStack栈的特性:
先进后出,后进先出。
而这个值栈存储方式是以针对Action类再以键值对的方式存放有关该Action的相关属性和信息。
如:
而这个值栈空间是一个Map集合,key就是自定义的name,而value是一个对象数组,可以对应同一个name设置多个值,添加后通过像数组下标方式来获取值。
如:
errrors.userName[0]取到第一个值。
同时这个Map中也将该Action中所有的属性也存入进来了,这样也很方便取到定义的Action属性值。
所以,这是struts2一个很好与页面的交互方式之一。
10.3获取request、session、application、HttpServletRequest、HttpSession、ServletContext的引用:
第一种方式:
在Action中声明一个Map类型的对象,通过在构造函数中进行初始化
privateMapsession;
session=ActionContext.getContext().getSession();
这时再使用session装值,在页面上通过
propertyvalue="#session.s1"/>|<%=session.getAttribute("s1")%>获取到值。
第二种方式:
该Action实现一个对应的对象的Aware接口,比如你要使用request对象,就实现requestAware接口,现时也声明一个privateMaprequest;然后再实现接口的setRequest方法。
这时在其它方法中就可以对request.put值,在页面上也就可以获取到相应的数据了。
propertyvalue="#request.s1"/>|<%=request.getAttribute("s1")%>
这种方式是采用的Ioc或DI的设计方式来实现的,也就是Spring中的控制反转来实现的。
依赖注入(DependencyInjectionDI):
在本身类中声明的类型对象,再依赖另的类通过参数传递(注入)方式来实现化此对象的过程。
就是将原来在自身类中需要初始化的过程,现在交给所依赖的类来实现
控制反转(Inverseofcontrol):
就是将原来自己控制成员实例的过程,现在交给所依赖的类去完成。
这就是控制权的反转了。
第三种方式:
获取Http对象,是通过声明定义HttpServletRequest类型对象,初始化是通过
ServletActionContext.getRequest()来获取。
第四种方式:
获取Http对象,是通过实现ServletRequestAware接口的依赖注入方式来实现。
11.默认Action是将应用中找到不Action时就会自动转向默认的action,这样页面就不会给用户报出找不到而报错。
/default.jsp
12.Action总结
12.1实现一个Action常用的方式:
从ActionSupport继承。
12.2DMI的动态方法调用!
12.3通配符配置*{1}{2}…*_*
12.4简单参数验证addFieldError,一般很少使用struts2的UI标签
12.5访问Web元素,Map类型Ioc依赖Struts2;原始类型Ioc依赖Struts2
12.6Include包含文件
12.7默认action处理
五、Result配置
(一)Result的种类:
1.Dispatcher:
是jsp之间跳转,是在服务器端跳转;它不能跳转到action上
2.Redirect:
客户端跳转,显示jsp
3.Chain:
此跳转类型可以跳转到一个action
4.redirectAction:
5.freemarker:
6.httpheader:
7.stream:
下载时使用
8.velocity
9.xslt
10.plaintext
11.tiles
(二)Global-result
global-result的配置使用:
当在global-result的标签中配置了result时,在同package中的任意action里都可以使用此result。
如果是跨package时也可通过extends的方式来访问。
/main.jsp
在此package中的所有action返回值为mainpage时都回跳转到main.jsp页面。
而当其它package中要想使用此global-result时又怎么办呢?
可以通过extends来访问:
在struts2-code-2.1.8.1.jar包下有个struts-default.xml配置文件,该文件是Struts2的核心配置。
(三)DynamicResult
这种方式是需要在Action中声明一个String变量用于动态斌予将要转向的页面路径。
而在struts的配置文件中又的${r}OGNL表达式来获取此变量的值,而此变量是存放在valuestack中。
这样最终达到动态转向的目的。
(当然,在action中声明用于动态存放跳转路径的变量也要提供get、set方法才可以)。
${r}
${r}读取的是UserAction中声明的变量r的值,因为此变量是存放在值栈空间里的。
当然r必须有get、set方法才可以
(四)向连接传递参数
此种原理与上边的DynamicResult一样,通过在action定义好变量并可以动态斌值。
在struts的配置文件中通过OGNL表达式读取值栈中的属性值来实现向链接的URL拼接参数的目的。
/user_success.jsp?
t=${r}
(五)总结Result
1.常用四种类型:
a)dispatcher(默认)b)redirectc)chaind)redirectAction
2.全局结果集:
global-results|extends
3.动态结果(了解):
在action中保存一个属性,存储具体的结果location
4.传递参数:
a)客户端跳转才需要传递
b)${}表达式
六、OGNL(ObjectGraphNavigationLanguage)表达式
1.访问值栈中action的普通属性:
userNamepropertyvalue=”userName”/>
2.访问值栈中对象的普通属性(getset方法)propertyvalue="user.age"/>
3.访问值栈中对象的普通属性(getset方法)propertyvalue="cat.friend.name"/>
4.访问值栈中对象的普通方法:
propertyvalue="passWord.length()"/>
5.访问值栈中对象的普通方法:
propertyvalue="cat.mew()"/>
6.访问静态方法:
propertyvalue="@com.java.struts2.action.OgnlAction@s()"/>
这是一种固定格式的访问。
7.访问静态属性:
propertyvalue="@com.java.struts2.action.OgnlAction@STATIC"/>
8.访问普通类的构造方法:
propertyvalue="newcom.java.bean.User()"/>构造对象
9.在什么情况下值栈中会出现两个或多个action?
使用result的type为chain在服务端跳转到另外一个action时,这时值栈中就会将前面所经过的action压入栈空间里。
10.[]:
propertyvalue="[0]"/>表示:
访问值栈空间中所压存的action对象,可能存在多个。
七、Struts2拦截器
拦截器能在action被调用之前和被调用之后执行一些“代码”。
Struts2框架的大部分核心功能都是通过拦截器来实现的,并且大量的工作都是由拦截器来完成。
为什么package的extends值为struts-default,因为在此xml配置文件中有大量的默认拦截器l
八、Struts2的执行过程简单描述
在struts2中使用到的核心技术就是拦截器(Interceptor),在web.xml配置文件中可看到
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
这就是struts2的入口,当然在filter-mapping中设置的/*
是对url采用正则截取。
对所截取到的url进入StrutsPrepareAndExecuteFilter类的doFilter处理。
在StrutsPrepareAndExecuteFilter类里同时实现了两个接口,那就是StrutsStatics和Filter,StrutsStatics接口中全部定义的是字符串常量,而这些常量值是记录的xwork2中几大对象的类全名。
如:
HTTP_REQUEST=”com.opensymphony.xwork2.dispatchar.HttpServletRequest”等
另外Filter接口中定义了三个方法分别是:
init、doFilter、destroy
在StrutsPrepareAndExecuteFilter最关键的就是doFilter的实现,当然在init方法中加载了Struts2的有关配置文件内容并初始化了Dispatcher对象以及PrepareOperations和ExecuteOperations、List;request=prepare.wrapRequest(request)对r