Struts2学习笔记.docx
《Struts2学习笔记.docx》由会员分享,可在线阅读,更多相关《Struts2学习笔记.docx(23页珍藏版)》请在冰点文库上搜索。
Struts2学习笔记
Struts2项目的构建与配置
1.配置struts.xml
(1)配置struts.xml可以参考下载的struts-2.3.14.1-all.zip解压后的apps文件夹下的参考项目的struts.xml文件。
(2)主要的配置如下:
/hello.jsp
value="true"表示是开发模式,当修改了配置时服务器会自动加载修改后的配置,不需要中期服务器,方便开发。
(3)namespace="/"与浏览器的访问地址有关,namespace的默认值为空。
(4)/hello.jspaction的name值与浏览器的访问地址有关,当地址是“http:
//…/hello”时,浏览器就会返回result中的hello.jsp的页面。
2.配置web.xml
(1)配置web.xml也可以参考下载的struts-2.3.14.1-all.zip解压后的apps文件夹下的参考项目的web.xml文件
(2)主要配置如下:
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
3.配置Struts2的jar包
(1)复制下载的struts-2.3.14.1-all.zip解压后的apps文件夹下的参考项目的WEB-INF\lib文件夹下的所有的jar包到我们自己项目的WEB-INF\lib文件夹下即可。
Struts.xml的配置
1.package的属性与配置
(1)package的使用说明:
类似于Java程序里的package,主要用于区分同名的action。
在真正的项目开发中package通常来区分不同的模块。
例如:
…
(2)name属性:
用于区分不同的package,此属性不能省略不写。
(3)extends属性:
用于继承其他的package,继承了某个package就包含了某个package里的所有配置,此属性可以省略不写,默认继承struts-default。
(4)namespace属性:
表示浏览器访问的路径,此属性可以省略不写,默认为空,当此属性为空时,该package里的action可以匹配浏览的任何请求的action。
(5)abstract属性:
此属性的值为false表示此package非抽象的,若为true表示此package为抽象的。
2.action的属性与配置
(1)action的使用说明:
action是配置在package里的,一个package可以配置多个action,每一个action都可以处理一种请求,通常一个action就是一个含有publicStringexecute()方法的Java类,根据execute方法的不同的返回值来返回相应的页面给用户。
例如:
…
(2)name属性:
定义action的名称,也表示浏览器访问的路径。
(3)class属性:
定义该action所对应的具体的Java类,其值是具体的Java类的路径。
(4)method属性:
定义该action调用Java类的具体方法,调用的方法的返回类型必须是String类型,如果用户没有定义该属性,则默认调用execute方法。
(5)method动态方法调用(BMI)
可以在浏览器地址栏里动态的指定调用action的那一个方法,如:
http:
//localhost:
8080/Struts2/hello/hello!
add。
调用格式为:
http:
//…/action名!
方法名
(6)使用通配符动态调用action及其方法并动态的返回页面
例如:
/hello_{1}.jsp
/{1}_{2}.jsp
第一个action所对应的Java类已确定是:
com.lzw.HelloAction。
但是对于不同的请求会调用该Java类里的不同的方法,并返回不同的页面,如:
http:
//…/hello/hello_add,会调用add()方法,并返回hello_add.jsp页面;若想调用execute()方法,就会返回hello_execute.jsp页面,对应的请求就是:
http:
//…/hello/hello_execute。
第二个action所对应的Java类并未确定,此action更为灵活,会根据不同的请求调用不同的action(即:
Java类)以及其不同的方法,并返回不同的页面。
如在浏览器的地址栏输入:
http:
//…/hello/User_add,就会调用com.lzw.UserAction类里的add()方法,并返回User_add.jsp页面。
注意:
在项目开发的时候一定要谨记“约定优于配置”原则,要约定好各个文件、方法以及类的起名规则!
!
!
(7)请求向action传递参数
例如:
action里含有两个属性name与age,并且含有相应的get与set方法,则请求:
http:
//…/hello/hello_add?
name=lizhiwei&age=12,会把“lizhiwei”与“12”通过set方法赋值给name与age。
当action里还有一个属性u而且这个属性不是基本类型,而是User类型(用户自定义类型),该类型里也含有name与age属性和相应的set与get方法,若要通过请求的方式给u对象赋值,则请求如下:
http:
//…/hello/hello_add?
name=lizhiwei&age=12&u.name=li&u.age=13,该请求会使得u的name属性值为li,age值为13。
注意:
通过这种方法一定要定义好相应的set与get方法,否则无法传值!
!
!
(8)action实现ModelDriven接口,进行参数传递
例如:
当一个action里含有一个属性u而且这个属性不是基本类型,而是User类型(用户自定义类型),该类型里也含有name与age属性和相应的set与get方法,若要通过请求的方式给u对象赋值;由于action实现了ModelDriven接口,就会重写getModel()方法,此时在action里就不需要写属性u的set与get方法,但是需要用new来创建u对象(而不是Struts2自动创建)。
请求:
http:
//…/hello/hello_add?
name=li&age=13,会把u的name属性赋值为li,age属性赋值为13。
重写getModel()方法的代码如下:
publicUsergetModel()
{
returnu;
}
(9)参数传递的乱码简单解决方式:
在struts.xml配置如下代码:
根据配置value的值来配置编码,但是请求方式应尽量使用post,避免使用get。
注意:
此方式在某些Struts2版本中使用时并不能解决问题,是因为那些版本存在bug。
本次实验使用的是struts-2.3.14.1版本,能够成功解决乱码问题!
(10)action的简单数据验证
如果action需要对接收到的参数进行验证,而要把验证到的信息返回给页面显示,常用且简单的做法是让此action继承ActionSupport,并在方法里增加相应验证代码,例如:
publicStringadd()
{
if(name==null||"".equals(name))
{
this.addFieldError("name","参数不能为空!
");
}
return"hello";
}
其中的this.addFieldError("name","参数不能为空!
")就是向ValueStackContents里添加错误信息(也可以向一个参数名添加多个错误信息),添加的信息可以在页面里取出来。
在页面里取出错误信息的代码如下:
fielderrorname="name">
fielderror>
当错误信息不为空时,错误信息就会显示出来,但是要想使用这些标签必须还要在页面里添加以下代码:
<%@tagliburi="/struts-tags"prefix="s"%>
(11)在action里访问Web元素(request、response、session、application等)
a)例如:
用户登录后action把用户名放到session里,在action里的主要代码如下:
privateMapsession;
publicStringadd()
{
session=ActionContext.getContext().getSession();//得到session
session.put("name",name);//设置值到session里
return"hello";
}
在前台JSP页面里取的name值得代码如下:
<%Stringname=(String)session.getAttribute("name");%>
<%=name%>
也可也使用Struts2的标签取得name值,具体代码如下:
propertyvalue="#session.name"/>
注意:
上面action里得到的session对象并不是真正服务器里的session对象,且该session对象是Map类型的,它只是Struts2模拟的session,只是Struts2能够把开发对此session的操作映射到真正的session上去。
所以操作此session是等效的。
b)第二种在action里取得Web元素的方法,此时的action要实现SessionAware接口,并重写里的setSession方法,具体实现如下:
(此种方式最常用)
publicvoidsetSession(Maparg0)
{session=arg0;}
c)第三种在action里取得Web元素的方法,此方法并不常用,代码如下:
privateHttpServletRequestrequest=ServletActionContext.getRequest();
privateHttpSessionsession=request.getSession();
privateServletContextapplication=session.getServletContext();
d)第四种在action里取得Web元素的方法,此方法是action实现ServletRequestAware接口,重写如下方法:
(此方法也不常用)
publicvoidsetServletRequest(HttpServletRequestarg0)
{
HttpServletRequestrequest=arg0;
HttpSessionsession=request.getSession();
ServletContextapplication=session.getServletContext();
}
(12)默认action的配置
例如下面的配置:
/UnderConstruction.jsp
使用了default-action-ref定义了默认的action,定义默认action后,当用户访问此namespace下的不存在的action时,这些请求都会交给默认的action处理。
3.result的属性与配置
(1)使用说明:
result是配置在action里的,用来定义action的处理后返回给用户的页面。
例如:
/hello/Error.jsp
(2)name属性:
action处理请求会返回一个字符串与此属性的值匹配,若匹配成功服务器就会返回该result所映射的页面。
此属性的常用值有:
"success、none、error、input、login";默认值是success。
(3)type属性:
此属性的值与页面的跳转方式有关,此属性值有:
chain、dispatcher、freemarker、httpheader、redirect、redirect-action、stream、velocity、xslt、plaintext,其中最常用的有:
dispatcher、redirect、chain、redirect-action。
其具体的含义如下:
dispatcher:
是默认值,表示服务器跳转,只能跳转到页面,不能是action。
redirect:
客户端跳转到页面,不能是action。
chain:
表示服务器跳转到一个action。
redirect-action:
客户端跳转到action。
(4)配置全局的result,例如:
/Error.jsp
/Error.jsp
Logon!
input
配置了global-results在一个package内的所有的action里就都含有了这些result的配置,相当于这个package里所有的action共用这些result。
(5)利用result动态的返回结果集,配置如下:
${r}
使用“$”与“{}”来动态的得到跳转的页面路径,其中的参数“r”就是action里的一个属性,此action对应的HelloAction.java文件的主要代码如下:
publicStringadd()
{
r="/index.jsp";
returnSUCCESS;
}
其实当action执行add方法时使得r的值为“/index.jsp”,执行完毕后该action所有属性都保存到了ValueStackContents之中,而result里的“${r}”会取到r的值,就会跳转到index.jsp页面了。
(6)带参数的结果集,类似于上例,配置如下:
/login.jsp?
name=${r}
其实现的原理与上例相同,但是值得注意的是:
只有当使用客户端跳转时才要传递参数。
4.超链接路径问题的说明
(1)问题的引出
action的配置如下:
/hello.jsp
helo.jsp页面的主要代码如下:
进入index.jsp
与hello.jsp文件同一位置的index.jsp文件的主要代码如下:
index
在浏览器地址栏输入“http:
//localhost:
8080/Struts2/hello/hello”访问hello.jsp效果如下:
点击超链接,效果如下:
(注意浏览器的地址栏)
出现了404错误!
由于namespace="/hello"把hello.jsp的路径映射成…/hello/hello,从而导致hello.jsp中的超链接路径也成了…/hello/index.jsp,也就出现404地址错误了。
(2)解决此路径问题的方法
只要使用了绝对路径便可解决该问题,具体做法是在hello.jsp文件中添加如下代码:
<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+":
//"+request.getServerName()+":
"+request.getServerPort()+path+"/";
%>
此时的basePath的值就是当前的文件路径,在使用超链接时只需要把该值加到前面即可,例如:
">进入index.jsp
还可以使用base标签更为方便的解决问题,只需要在head标签里加入如下代码:
">此时超链接的写法不变还是进入index.jsp
5.include的属性与配置
(1)使用说明:
使用include可以把struts.xml文件模块化,每个模块都可以是一个xml配置文件,使用include把其中的每个模块导入到struts.xml文件里,便于项目开发时的模块的划分与分配。
例如:
(2)file属性:
其值是需要导入的配置文件地址。
6.声明式的异常处理
(1)使用说明:
使用exception-mapping配置action的异常处理页面。
/Login.action
/DataAccess.jsp
(2)exception属性:
配置异常的类型,此类型应该和action程序抛出的异常类型相对应。
(3)result属性:
此类型的值表示出异常后的返回页面位置,与相应的result的配置对应。
(4)在配置时为每个action都配置异常实在太繁琐,这时就可以使用全局的异常处理,如下(该配置应放在package里):
7.i18n国际化
(1)action级别的国际化
使用action级别的国际化,该action必须继承ActionSupport,而且国际化资源文件必须与该action在同一目录下,文件名也必须是该action的类名加后缀(如:
LoginAction_en_US.properties);取得该资源文件的方式是在JSP页面里使用以下语句:
propertyvalue="getText('login.name')"/>,其实该代码是调用了当前action的getText方法。
(2)包(package)级别的国际化
使用包级别的国际化,国际化资源文件必须在该包的目录下,文件名也必须是类似package_en_US.properties的形式,前缀必须是package。
(3)APP级别的国际化
使用APP级别的国际化,国际化资源文件必须与st