struts2.docx
《struts2.docx》由会员分享,可在线阅读,更多相关《struts2.docx(26页珍藏版)》请在冰豆网上搜索。
struts2
新建struts工程步骤:
1、新建webproject,
2、拷贝struts.xml文件,路径为struts2.3.16-all\struts-2.3.16\apps\struts2-blank\WEB-INF\classes
3、拷贝类库,路径为:
F:
\程序\struts2.3.16-all\struts-2.3.16\apps\struts2-blank\WEB-INF\lib
3、Copyweb.xml文件中的关于filter和filter-mapping的设置,路径为F:
\程序\struts2.3.16-all\struts-2.3.16\apps\struts2-blank\WEB-INF
4、
工程目录的建立:
如果web下只有一个action,那么如果想在action下再建立一个包,则如下图示:
只需要把action改为biz就行。
结果如下图所示:
Struts2实质是就是把请求与视图分开。
Namespace决定了访问路径,默认为“”(如果没有namespace这一项也相当于“”空,用来处理其他package处理不了的action(只要action名字为请求的action名字),即没有其他package能与它更准确的对应时由namespace为空的来处理),表示接收所有路径的action。
最好用模块来命名。
凡是名字为success的result都可以把名字省略。
Struts2起源于webwork框架,也是一个MVC框架。
Web.xml中配置与struts2相关的信息:
index.jsp
--配置struts2过滤器-->
struts2
--过滤器名称-->
--过滤器类-->
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
--过滤器映射-->
Struts2框架主要是通过一个过滤器将struts集成到web应用中,通过它Struts2可拦截web应用中的http请求,并将http请求发送到指定的action处理,action根据处理的结果返回客户端页面。
因此过滤器是web应用与struts2API之间的入口。
通过过滤器拦截要处理的请求,当客户发送一个http请求时,需要经过一个过滤器链。
这个过滤器链包括ActionContextClearUp过滤器,其他web应用过滤器及StrutsPrepareAndExecuteFilter过滤器,其中StrutsPrepareAndExecuteFilter是必须配置的(在web.xml中配置)。
当StrutsPrepareAndExecuteFilter被调用时,Action将查找需要调用的Action对象,并返回对象的代理。
然后Action代理将从配置管理器中读取Struts2的相关配置(sturts.xml)。
Action容器调用指定的Action对象,在调用之前需要经过Struts2的一系列拦截器。
拦截原理模拟:
在struts.xml中如下配置解析:
method="{1}">
其中*为通配符,method本来表示action中的哪个方法,等号后跟具体方法名字,但也可以用method="{1}"方式,其中{1}表示匹配通配符。
Struts2应用主要技术还是webwork。
Struts.xml:
设置为开发模式,作用是每次修改都会立即有反馈,便于开发调试。
Windows---showview--webbrowser
Struts2把请求和视图分开。
Package用来处理重名的action
名字为success的result可以不写name=“success”即中没其他内容时,相当于,即没有名字的result名字默认为success
Namespace为空,表示name=“”,则只要是index找不到与它对应的namespace都由为空的namespace处理。
当action没有配置class时默认执行ActionSupport.class
(它是xwork原码)其中有个excute方法返回“success”字符串
实现execute三种访求:
一是extendsActionSupport(开发时用的,因为ActionSupport已经定义了很多方便我们使用的方法,子类里可以直接拿来用)
二是ImplementActon
三是
Jsp中常出现以下代码:
<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+":
//"
+request.getServerName()+":
"+request.getServerPort()
+path+"/";
%>
最后basePath=“http:
//localhost:
8080/项目名/
Head里再加这样一句">,这样就指定了该jsp中所有文件路径前默认加basePath。
request.getContextRoot方式拿到webapp路径。
约定优于配置:
为了配置的简单,必须约定好。
DMI(动态方法调用)
通配符:
/Student{1}_success.jsp
如果请求的是studentadd,则{1}匹配add,调用Studentadd_success.jsp,
如果请求的是studentdel,则{1}匹配del,调用Studentdel_success.jsp,
/{1}_{2}_success.jsp
优先匹配最精确的action的。
只要有*号则优先级相同,如果有两个*符合则匹配最前面一个。
Struts.xml配置:
Struts2-core-2.2.3.jar---org.apache.struts2----static--default.properties中
意思是对Struts.xml配置都会在上面的default.properties中体现出来,同时default.properties也告诉你struts的项分别是什么作用。
设置的时候可以参考这个文件,当遇到某个项目中的struts.xml文件中有没有见过的项时可以参考这个文件看看该项是什么作用的。
UTF8是国际编码,它的通用性比较好,外国人也可以浏览论坛,GBK是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大~
即用utf-8,即使外国人访问页面也显示中文。
而GBK只是中国标准,老外访问时会显示乱码,所以一般都通用utf-8。
add?
info=5">添加用户表示到命名空间为/user的package中寻找匹配的action(名字为userAction的action),并调用该action中的方法add,同时向该方法传递参数info。
(注意是向该方法传递参数,而不是向整个action传递参数,另外注意参数传递方式:
方法名?
参数=value)。
详情见struts1工程。
DomainModel:
域模型接收参数(用的最多)
Index中这样写:
add?
user.name=lily">添加用户
update?
user.age=5">修改用户
表示到命名空间为/user的package中寻找匹配的action(名字为userAction的action),并调用该action中的方法add,同时向该方法传递参数user.age=5。
userAction对应的action为UserAction,其中有getUser(),该函数会接收user信息,然后在该action中打印user.getName(),其中getName()是类User的一个函数。
(实际上在此过程中struts2帮着我们new了一个user)。
ModelDriven:
<%@tagliburi="/struts-tags"prefix="s"%>指定用struts标签,且是s标签。
Valuestack:
值栈,里面存键值对(key-value)。
只不过对于error来说,value是一个map型,而map又是key-value类型,而map中的value又是数组类型。
关系如下面第二图所示:
Errors:
包含下面两种错误
actionErrors:
action本身错误
fieldErrors:
校验属性时错误(field指的就是action中属性)
详细代码见SimpleDataValiation
propertyvalue="errors/>就是把error的value值也就是map类型取出来。
Action中有以下代码:
this.addFieldError("n","nameiserror");
this.addFieldError("m","nameistoolong");
this.addFieldError("pp","nameispp1");
this.addFieldError("pp","nameispp3");
返回jsp中
fielderrorfieldName="n"/>
fielderrorfieldName="m"/>
propertyvalue="errors"/>
propertyvalue="errors.n"/>
propertyvalue="errors.m"/>
propertyvalue="errors.n[0]"/>
propertyvalue="errors.m[0]"/>
第二组
fielderrorfieldName="pp"/>
propertyvalue="errors.pp"/>
propertyvalue="errors.pp[0]"/>
propertyvalue="errors.pp[1]"/>
显示结果为:
∙nameiserror
∙nameistoolong
{n=[nameiserror],m=[nameistoolong],pp=[nameispp1,nameispp3]}
[nameiserror]
[nameistoolong]
nameiserror
nameistoolong
第二组
∙nameispp1
∙nameispp3
[nameispp1,nameispp3]
nameispp1
nameispp3
request=(Map)ActionContext.getContext().get("request");就是把Context中的request的value值取出来,这个值为Map类型
用ActionContext就是action执行时的环境(上下文),一些内容封装进去。
Attr搜session、request和application中的值。
对应Struts2_1200_AccessWebElements项目
Maprequest;
说明:
request本身是Map类型,而Map类型又是key-value形式,也就是说request的key是String,而value是Object。
RequestAware:
(可以理解为知道request接口),action继承该接口后,struts的filter就会发觉到,然后filter把从servlet容器中获取的httprequest转化成Map类型用setRequest(Maprequest)函数传给action,然后在action中就可以用这个request了,比如执行request.put()函数。
也就是struts2帮action初始化了request。
这就是所谓的DI(dependencyinjection)依赖注入(action的request依赖于strut2容器注入)。
SessionAware:
(可以理解为知道Session接口)。
ApplicationAware:
(可以理解为知道Application接口)
DI:
dependencyinjection依赖注入
IoC:
inverseofcontrol控制反转(由别人控制注入,本来是自己控制,现在由别人控制,就反转了)
Struts.xml中include:
目的是为了在各人负责不同模块时不会造成因共用Struts.xml而出现的错误。
default-action-ref:
访问到不存在的action时跳转到默认的action,目的就是在找不到action时不至于出现错误页面。
/user_login_success.jsp
/default.jsp
奋进
Struts.xml中的result类型配置()
但是跳转不到action中
Dispatcher:
服务器跳转到视图(jsp或html文件)
Redict:
客户端跳转到视图,但是显示jsp地址。
Chain:
服务器(forward)跳转到action,如果action在另外一个包中要加上packagename/actonname
Redictaction:
客户端跳转到另外一个action
Stream:
下载
Plaintext:
显示真正的页面原码(教学用)
/r11.jsp
/r2.jsp
r2
r3
无论中间的链接有多长,关键是最后一个result是什么类型的,如果最后一个是redirect,那么都会在浏览器的地址栏中显示jsp名字,即++.jsp。
如上面例子向r4发请求时地址栏中显示:
http:
//localhost:
8080/Struts2_1500_ResultType/r2.jsp
如果把上面的r3改一下,变为:
r1
在向r4发请求时那么地址栏中会有以下显示:
http:
//localhost:
8080/Struts2_1500_ResultType/r/r4
redirectAction和chain都用来访问action,区别在于前者在地址栏里显示的是最后的action名字或jsp。
而chain显示的请求的action名字,当然chain在遇到最后一个result为redirect类型时也会只显示jsp名字。
Struts.xml中的extends作用:
从另外一个package里面继承,形式为extends=“packagename”
Struts.xml中${r}:
用来在配置文件里从valuestack中取值。
(DynamicResult项目中),注意不是EL表达式。
一次request只有一个值栈
forward和redirect的区别
Forward:
服务器跳转
Redirect:
浏览器跳转
一句话,转发是服务器行为,重定向是客户端行为。
为什么这样说呢,这就要看两个动作的工作流程:
转发过程:
客户浏览器发送http请求----》web服务器接受此请求--》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。
在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。
转发行为是浏览器只做了一次访问请求。
重定向过程:
客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器--》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。
在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。
在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。
重定向行为是浏览器做了至少两次的访问请求的。
解释二
重定向,其实是两次request,
第一次,客户端requestA,服务器响应,并response回来,告诉浏览器,你应该去B。
这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。
重定向可以访问自己web应用以外的资源。
在重定向的过程中,传输的信息会被丢失。
例子:
请求转发是服务器内部把对一个request/response的处理权,移交给另外一个
对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。
传输的信息不会丢失。
例子:
解释三
假设你去办理某个执照,
重定向:
你先去了A局,A局的人说:
“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。
OGNL:
ObjectGraphNavigationLanguage对象图导航语言
1、只有把user.xx传进去,才会构造对象。
想初始化domainmodel,可以自己new一个对象,也可以通过传值让系统自己构造(前提是有一个参数为空的构造方法)
迭代式开发:
最流行的开发模式
propertyvalue="username"
OGNL表达式讲的就是双引号中的内容
属性和方法排序:
右单击---Source---SortMembers---对话框中选择“SortallNumbers”
Struts2常量查询:
struts2-cor-2.1.6.jar--defaultproperties
允许访问静态方法设置:
投影(过滤):
propertyvalue="users.{?
#this.age==1}[0]"/>
Users是一个集合,?
#给users做过滤时会把所有users对象拿出来,this指的就是每个对象,users.{?
#this.age==1}的意思就是把users中age=1的对象全拿出来,因为是个集合,所以结果会是[………………],因此后面的的[0]就是取符合条件的第一个。
propertyvalue="users.{^#this.age>1}.{age}"/>---找出第一个age大于1的对象的age值的集合,是集合的原因:
比如有两个age值为2,那么结果就是[2,2].
propertyvalue="users.{$#this.age>1}.{age}"/>--找出最后一个age大于1的对象的age值的集合,是集合的原因:
比如有两个age值为10,那么结果就是[10,10].
Struts.xml中不能处理OGNL语