第一天上午学习目录列表:
一、第一个struts2.1应用开发
二、Action配置的各项默认值
三、配置的各种视图转发类型
四、Action属性注入值
五、Struts 2.1处理的请求
开发环境:MyEclipse+Tomcat6.x
一、第一个struts2应用开发
1.1、开发Struts 2程序最少需要的JAR如下:
struts2-core-2.x.x.jar :Struts 2框架的核心类库
xwork-core-2.x.x.jar :XWork类库,Struts 2在其上构建
ognl-2.6.x.jar :对象图导航语言(Object Graph Navigation Language),struts2框架通过其读写对象的属性
freemarker-2.3.x.jar :Struts 2的UI标签的模板使用FreeMarker编写
commons-logging-1.x.x.jar :ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。
commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后必须加入此文件
1.2、Struts2默认的配置文件为struts.xml ,该文件需要存放在WEB-INF/classes下,该文件的配置模板如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3C!DOCTYPE%20struts%20PUBLIC%0A%20%20%20%20%22-%2F%2FApache%20Software%20Foundation%2F%2FDTD%20Struts%20Configuration%202.0%2F%2FEN%22%0A%20%20%20%20%22http%3A%2F%2Fstruts.apache.org%2Fdtds%2Fstruts-2.0.dtd%22%3E%0A%3Cstruts%3E%0A%3C%2Fstruts%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- < struts >
- </ struts >
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
</struts>
知识提示 : 此模板可在struts-2.1.6\apps\struts2-blank-2.1.6.war的空白项目里面拷.
1.3、struts2框架是通过Filter启动的。他在web.xml中的配置如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cfilter%3E%0A%20%20%20%20%3Cfilter-name%3Estruts2%3C%2Ffilter-name%3E%0A%20%20%20%20%3Cfilter-class%3Eorg.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter%3C%2Ffilter-class%3E%0A%20%3C!--%20%E8%87%AA%E4%BB%8EStruts%202.1.3%E4%BB%A5%E5%90%8E%EF%BC%8C%E4%B8%8B%E9%9D%A2%E7%9A%84FilterDispatcher%E5%B7%B2%E7%BB%8F%E6%A0%87%E6%B3%A8%E4%B8%BA%E8%BF%87%E6%97%B6%0A%20%20%20%20%3Cfilter-class%3Eorg.apache.struts2.dispatcher.FilterDispatcher%3C%2Ffilter-class%3E%20--%3E%20%0A%3C%2Ffilter%3E%0A%3Cfilter-mapping%3E%0A%20%20%20%20%3Cfilter-name%3Estruts2%3C%2Ffilter-name%3E%0A%20%20%20%20%3Curl-pattern%3E%2F*%3C%2Furl-pattern%3E%0A%3C%2Ffilter-mapping%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < filter >
- < filter-name > struts2 </ filter-name >
- < filter-class > org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </ filter-class >
- <!-- 自从Struts 2.1.3以后,下面的FilterDispatcher已经标注为过时
- < filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class > -- >
- </ filter >
- < filter-mapping >
- < filter-name > struts2 </ filter-name >
- < url-pattern > /* </ url-pattern >
- </ filter-mapping >
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- 自从Struts 2.1.3以后,下面的FilterDispatcher已经标注为过时
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> -->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
知识提示 : 在StrutsPrepareAndExecuteFilter的init()方法中将会加载类路径下默认的配置文件struts.xml完成初始化操作,些初始化工作只做一次,在服务器启动过程中完成.
1.4、第一个Struts2版HelloWorld.
1.4.1、新建cn.gkit.action.HelloWorldAction类,代码如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20HelloWorldAction%20%7B%0A%09%0A%09private%20String%20message%3B%0A%09public%20String%20getMessage()%20%7B%0A%09%09return%20message%3B%0A%09%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E8%BF%94%E5%9B%9E%E7%9A%84%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%0A%09public%20String%20execute()%7B%0A%09%09message%20%3D%20%22struts2%E7%89%88%E7%9A%84HelloWorld%22%3B%0A%09%09return%20%22success%22%3B%0A%09%7D%0A%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public class HelloWorldAction {
-
- private String message;
- public String getMessage() {
- return message;
- }
-
- public String execute(){
- message = "struts2版的HelloWorld" ;
- return "success" ;
- }
- }
public class HelloWorldAction {
private String message;
public String getMessage() {
return message;
}
//返回的是一个字符串
public String execute(){
message = "struts2版的HelloWorld";
return "success";
}
}
知识提示 : 可以看到此Action类并没有继承其它类,是一个简单的POJO类.
1.4.2、action在struts.xml里的配置:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%20%3F%3E%0A%3C!DOCTYPE%20struts%20PUBLIC%0A%20%20%20%20%22-%2F%2FApache%20Software%20Foundation%2F%2FDTD%20Struts%20Configuration%202.0%2F%2FEN%22%0A%20%20%20%20%22http%3A%2F%2Fstruts.apache.org%2Fdtds%2Fstruts-2.0.dtd%22%3E%0A%3Cstruts%3E%0A%20%20%20%3Cpackage%20name%3D%22test%22%20namespace%3D%22%2Ftest%22%20extends%3D%22struts-default%22%3E%0A%20%20%20%20%20%20%20%20%3Caction%20name%3D%22helloworld%22%20class%3D%22cn.gkit.action.HelloWorldAction%22%20method%3D%22execute%22%20%3E%0A%09%3Cresult%20name%3D%22success%22%3E%2FWEB-INF%2Fjsp%2Fhelloworld.jsp%3C%2Fresult%3E%0A%20%20%20%20%20%20%20%20%3C%2Faction%3E%0A%20%20%20%20%3C%2Fpackage%3E%20%20%20%0A%3C%2Fstruts%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <?xml version= "1.0" encoding= "UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd" >
- <struts>
- <package name= "test" namespace= "/test" extends = "struts-default" >
- <action name="helloworld" class = "cn.gkit.action.HelloWorldAction" method= "execute" >
- <result name="success" >/WEB-INF/jsp/helloworld.jsp</result>
- </action>
- </package >
- </struts>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="test" namespace="/test" extends="struts-default">
<action name="helloworld" class="cn.gkit.action.HelloWorldAction" method="execute" >
<result name="success">/WEB-INF/jsp/helloworld.jsp</result>
</action>
</package>
</struts>
知识 提示 :<package> 表示一个包,类似java包. 此包可以被其它包继承.继承的属性是extends. test包就继承了一个struts的默认包struts-default.struts-default包定义在struts-defautl.xml 配置文件里,可以在struts2核心包根路径下面找到.namespace属性表示命名空间,可以把请求路径相同的一部分抽取出来。如访问 helloworld请求的路径为:/struts2.1/test/helloworld,其中struts2.1是指向该应用程序的虚拟目录(即内容 路径).<result>表示返回的视图,具体配置会在第三章中讲到.
1.4.3、在helloworld.jsp显示message信息:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%25%40%20page%20language%3D%22java%22%20import%3D%22java.util.*%22%20pageEncoding%3D%22UTF-8%22%25%3E%0A%3C!DOCTYPE%20HTML%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20HTML%204.01%20Transitional%2F%2FEN%22%3E%0A%3Chtml%3E%0A%20%20%3Chead%3E%0A%20%20%20%20%3Ctitle%3Estruts2.1%E7%89%88HelloWorld%3C%2Ftitle%3E%0A%20%20%3C%2Fhead%3E%0A%20%20%3Cbody%3E%0A%20%20%20%20%24%7Bmessage%7D%0A%20%20%3C%2Fbody%3E%0A%3C%2Fhtml%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <%@ page language= "java" import = "java.util.*" pageEncoding= "UTF-8" %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
- <html>
- <head>
- <title>struts2.1 版HelloWorld</title>
- </head>
- <body>
- ${message}
- </body>
- </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>struts2.1版HelloWorld</title>
</head>
<body>
${message}
</body>
</html>
知识 提示 :用el表达式可以将action里的属性取出来.
二、Action配置(struts.xml--<action>)的各项默认值
1>如果没有为action指定class属性,默认是ActionSupport。
2>如果没有为action指定method属性,默认执行action中的execute() 方法。
3>如果没有指定result的name属性,默认值为success。
如在test包里增加如下一个action请求
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Caction%20name%3D%22registerUI%22%3E%0A%20%20%20%20%20%3Cresult%3E%2FWEB-INF%2Fpage%2Fregister.jsp%3C%2Fresult%3E%0A%3C%2Faction%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < action name = "registerUI" >
- < result > /WEB-INF/page/register.jsp </ result >
- </ action >
<action name="registerUI">
<result>/WEB-INF/page/register.jsp</result>
</action>
知识提示: 当访问路径/struts2.1/test/registerUI时,返回给浏览器的就是register.jsp页面.配置相当于struts1.x,如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Caction%20path%3D%22%2Ftest%2FregiterUI%22%20forward%3D%22%2FWEB-INF%2Fpage%2Fregister.jsp%22%2F%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < action path = "/test/regiterUI" forward = "/WEB-INF/page/register.jsp" />
<action path="/test/regiterUI" forward="/WEB-INF/page/register.jsp"/>
三、配置的各种视图转发类型
<result>配置类似于struts1中的<forward>,但struts2中提供了多种结果类型,常用的类型有: dispatcher(默认值)、 redirect(重定向) 、 redirectAction 、 plainText (文本).
3.1、redirect
但在<result>中还可以使用${属性名}表达式访问action中的属性,表达式里的属性名对应action中的属性。
将1.4.2里的struts.xml配置文件里的<result>改成如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cresult%20type%3D%22redirect%22%3E%2Fhelloworld.jsp%3Fmessage%3D%24%7Bmessage%7D%3C%2Fresult%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < result type = "redirect" > /helloworld.jsp? message =${message} </ result >
<result type="redirect">/helloworld.jsp?message=${message}</result>
知识提示: 此时的helloworld.jsp应放在WebRoot目录下才可重定向访问.而在struts1.x的配置文件里的是做不到这一点的. 除非使用urlrewrite重写url,但也不能传一个action里的属性值. 重新访问/struts2.1/test/helloworld请求,浏览器地址将变为/struts2.1 /helloworld.jsp?message=struts2H凥elloWorld.这里先忽略中文乱码问题.
3.2、plaintext:显示原始文件内容,例如:当我们需要原样显示jsp文件源代码的时候,我们可以使用此类型。配置如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cresult%20name%3D%22source%22%20type%3D%22plainText%20%22%3E%0A%09%3Cparam%20name%3D%22location%22%3E%2Fview.jsp%3C%2Fparam%3E%0A%09%3Cparam%20name%3D%22charSet%22%3EUTF-8%3C%2Fparam%3E%3C!--%20%E6%8C%87%E5%AE%9A%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6%E7%9A%84%E7%BC%96%E7%A0%81%20--%3E%20%20%20%0A%3C%2Fresult%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <result name= "source" type= "plainText " >
- <param name="location" >/view.jsp</param>
- <param name="charSet" >UTF- 8 </param><!-- 指定读取文件的编码 -->
- </result>
<result name="source" type="plainText ">
<param name="location">/view.jsp</param>
<param name="charSet">UTF-8</param><!-- 指定读取文件的编码 -->
</result>
知识提示: 当访问该请求时,返回的一个jsp页面代码文体视图,即jsp页面代码将不会被执行.
3.3、redirectAction作用与redirect类似,不同的是它重定向的是一个action.
四、Action属性注入值
属性注入类似于spring的属性注入,原理上是一样的, 都是通过反射技术将xml对应的值设值到相对应的java属性里.被注入的属性也要有对应的setter方法.
1、在HelloWorldAction 类里增加一下setter方法:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20void%20setMessage(String%20message)%20%7B%0A%09%09this.message%20%3D%20message%3B%0A%09%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public void setMessage(String message) {
- this .message = message;
- }
public void setMessage(String message) {
this.message = message;
}
2、为了避免覆盖,将execute方法里给message赋值的那一段代码注释掉.
3、在struts.xml配置文件的<action>增加一个子标签<param name="">,配置改成如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%20%20%20%3Cpackage%20name%3D%22test%22%20namespace%3D%22%2Ftest%22%20extends%3D%22struts-default%22%3E%0A%20%20%20%20%20%20%20%20%3Caction%20name%3D%22helloworld%22%20class%3D%22cn.gkit.action.HelloWorldAction%22%20method%3D%22execute%22%20%3E%0A%20%20%20%20%20%20%20%20%09%3Cparam%20name%3D%22message%22%3E%E5%B1%9E%E6%80%A7%E6%B3%A8%E5%85%A5%3C%2Fparam%3E%0A%09%3Cresult%20name%3D%22success%22%3E%2FWEB-INF%2Fjsp%2Fhelloworld.jsp%3C%2Fresult%3E%0A%20%20%20%20%20%20%20%20%3C%2Faction%3E%0A%20%20%20%20%3C%2Fpackage%3E%20%20%20" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < package name = "test" namespace = "/test" extends = "struts-default" >
- < action name = "helloworld" class = "cn.gkit.action.HelloWorldAction" method = "execute" >
- < param name = "message" > 属性注入 </ param >
- t;result name = "success" > /WEB-INF/jsp/helloworld.jsp </ result >
- </ action >
- </ package >
<package name="test" namespace="/test" extends="struts-default">
<action name="helloworld" class="cn.gkit.action.HelloWorldAction" method="execute" >
<param name="message">属性注入</param>
<result name="success">/WEB-INF/jsp/helloworld.jsp</result>
</action>
</package>
此时访问该请求,页面显示的mesage属性值为: 属性注入
五、Struts 2处理的请求
1、指定需要Struts 2处理的请求后缀,配置文件struts.xml配置里增加一下常量标签<constant>
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3C!DOCTYPE%20struts%20PUBLIC%0A%20%20%20%20%22-%2F%2FApache%20Software%20Foundation%2F%2FDTD%20Struts%20Configuration%202.0%2F%2FEN%22%0A%20%20%20%20%22http%3A%2F%2Fstruts.apache.org%2Fdtds%2Fstruts-2.0.dtd%22%3E%0A%3Cstruts%3E%0A%20%20%20%20%3Cconstant%20name%3D%22struts.action.extension%22%20value%3D%22do%22%2F%3E%0A%3C%2Fstruts%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- < struts >
- < constant name = "struts.action.extension" value = "do" />
- </ struts >
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.action.extension" value="do"/>
</struts>
2、如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号隔开。如:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cconstant%20name%3D%22struts.action.extension%22%20value%3D%22do%2Chtm%22%2F%3E%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < constant name = "struts.action.extension" value = "do,htm" />
<constant name="struts.action.extension" value="do,htm"/>
3、常量名struts.action.extension可以在default.properties里找到,里面包含了struts2默认的常量 值.default.properties可以在struts2核心包下的org.apache.struts2下找到.
第一天上午内容结束.
下午内容目录如下:
六、Struts2的处理流程与Action的管理方式
七、动态方法调用和使用通配符定义action
八、自定义类型转换器
九、自定义拦截器
十、文件上传
第一天下午学习目录列表:
六、Struts2的处理流程与Action的管理方式
七、动态方法调用和使用通配符定义action
八、自定义类型转换器
九、自定义拦截器
十、文件上传(改成一个专题来讲)
六、Struts2的处理流程与Action的管理方式
6.1struts2处理请求图
![](http://dl.iteye.com/upload/attachment/182812/14ebd1c7-6e99-3814-903f-cb0df6a13df7.jpg)
StrutsPrepareAndExecuteFilter是Struts 2框架的核心控制器(相当于strtuts1.x的ActionServlet类的作用 ), 它负责拦截由<url-pattern>/*</url-pattern>指定的所有用户请求,当用户请求到达时,该 Filter会过滤用户的请求。默认情况下,如果用户请求的路径不带后缀或者后缀以.action结尾,这时请求将被转入Struts 2框架处理,否则Struts 2框架将略过该请求的处理。当请求转入Struts 2框架处理时会先经过一系列的拦截器,然后再到Action。与Struts1不同,Struts2对用户的每一次请求都会创建一个Action,所以 Struts2中的Action是线程安全的。也正因为如此,Struts2里可以定义成员变量,从而废弃了Struts1.x里的Form Bean.即Struts2的Action已具备了Struts1.x里的Form Bean的功能.
七、动态方法调用和使用通配符定义action
7.1 动态方法调用
如果Action中存在多个业务方法时,我们可以使用!+方法名调用指定方法。 我们在HelloWorldAction里添加两个业务方法,如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%09public%20String%20del()%20%7B%0A%09%09message%20%3D%20%22%E8%B0%83%E7%94%A8del()%E5%88%A0%E9%99%A4%E6%96%B9%E6%B3%95%22%3B%0A%09%09return%20%22success%22%3B%0A%09%7D%0A%0A%09public%20String%20add()%20%7B%0A%09%09message%20%3D%20%22%E8%B0%83%E7%94%A8add()%E6%B7%BB%E5%8A%A0%E6%96%B9%E6%B3%95%22%3B%0A%09%09return%20%22success%22%3B%0A%09%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public String del() {
- message = "调用del()删除方法" ;
- return "success" ;
- }
-
- public String add() {
- message = "调用add()添加方法" ;
- return "success" ;
- }
public String del() {
message = "调用del()删除方法";
return "success";
}
public String add() {
message = "调用add()添加方法";
return "success";
}
如果要访问action的del() 方法,我们可以这样调用:/struts2.1/test/helloworld!del ,动态方法调用就是那么简单,它实现了跟struts1.x 的DispatchAction一样的作用.
注意: struts2的官方文档已经不建议我们这样使用,建议我们使用另外一种方式来实现: 使用通配符定义action来替代
7.2 使用通配符定义action
即用*号来表示在动态改变的字符或字符串.在struts.xml的test包中添加一个action,如下:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%20%3Caction%20name%3D%22*User%22%20class%3D%22cn.gkit.action.HelloWorldAction%22%20method%3D%22%7B1%7D%22%20%3E%0A%20%20%20%20%20%20%20%20%09%3Cparam%20name%3D%22message%22%3E%E5%B1%9E%E6%80%A7%E6%B3%A8%E5%85%A5%3C%2Fparam%3E%0A%09%3Cresult%20name%3D%22success%22%3E%2FWEB-INF%2Fjsp%2Fhelloworld.jsp%3C%2Fresult%3E%20%0A%20%3C%2Faction%3E" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < action name = "*User" class = "cn.gkit.action.HelloWorldAction" method = "{1}" >
- < param name = "message" > 属性注入 </ param >
- < result name = "success" > /WEB-INF/jsp/helloworld.jsp </ result >
- </ action >
<action name="*User" class="cn.gkit.action.HelloWorldAction" method="{1}" >
<param name="message">属性注入</param>
<result name="success">/WEB-INF/jsp/helloworld.jsp</result>
</action>
此时 如果要访问action的del() 方法,我们可以这样调用:/struts2.1/test/delUser 即可调用到del()方法.
知识提示: {1}表示与第一个*号匹配,{1}不但可以在method属性上使用,还可以在其他地方使用,如在<result>使用:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cresult%20name%3D%22success%22%3E%2FWEB-INF%2Fjsp%2F%7B1%7D.jsp%3C%2Fresult%3E%20%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- < result name = "success" > /WEB-INF/jsp/{1}.jsp </ result >
<result name="success">/WEB-INF/jsp/{1}.jsp</result>
八、自定义类型转换器
问题引入 :对于Date类型的属性,可以接收格式为2009-12-20的请求参数值,并将其自动转换成Date类型.但如果项目需求要接收形如:20091220格式的日期该怎么办,在struts1.x中我们可以通过定义类型转换器来实现,同样在Struts2.x里我们也可以定义类似的转换器,并且比struts1.x的转换器要强大,它实现了双向转换的功能.
8.1 定义局部类型转换器
首先在HelloWorldAction里增加一个java.util.Date 类型的birthday字段,并提供getter和setter方法.如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%09private%20Date%20birthday%3B%0A%0A%09public%20Date%20getBirthday()%20%7B%0A%09%09return%20birthday%3B%0A%09%7D%0A%0A%09public%20void%20setBirthday(Date%20birthday)%20%7B%0A%09%09this.birthday%20%3D%20birthday%3B%0A%09%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- private Date birthday;
-
- public Date getBirthday() {
- return birthday;
- }
-
- public void setBirthday(Date birthday) {
- this .birthday = birthday;
- }
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
然后: 定义Date类型转换器,定义转器有两种方式:
第一种是继承com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter类,重写它的convertValue方法,实现如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20DateTypeConverter%20extends%20DefaultTypeConverter%7B%0A%09%40Override%0A%09public%20Object%20convertValue(Map%3CString%2C%20Object%3E%20context%2C%20Object%20value%2C%0A%09%09%09Class%20toType)%20%7B%0A%09%09SimpleDateFormat%20dateFormat%20%3D%20new%20SimpleDateFormat(%22yyyyMMdd%22)%3B%0A%09%09try%20%7B%20%0A%09%09%09if(toType%20%3D%3D%20Date.class)%7B%2F%2F%E5%BD%93%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%90%91Date%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E6%97%B6%0A%09%09%09%09String%5B%5D%20params%20%3D%20(String%5B%5D)%20value%3B%2F%2F%20Request.getParameterValues()%20%0A%09%09%09%09return%20dateFormat.parse(params%5B0%5D)%3B%0A%09%09%09%7Delse%20if(toType%20%3D%3D%20String.class)%7B%2F%2F%E5%BD%93Date%E8%BD%AC%E6%8D%A2%E6%88%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%97%B6%0A%09%09%09%09Date%20date%20%3D%20(Date)%20value%3B%0A%09%09%09%09return%20dateFormat.format(date)%3B%0A%09%09%09%7D%0A%09%09%7D%20catch%20(ParseException%20e)%20%7B%7D%0A%09%09return%20null%3B%0A%09%09%7D%0A%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public class DateTypeConverter extends DefaultTypeConverter{
- @Override
- public Object convertValue(Map<String, Object> context, Object value,
- Class toType) {
- SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMdd" );
- try {
- if (toType == Date. class ){
- String[] params = (String[]) value;
- return dateFormat.parse(params[ 0 ]);
- }else if (toType == String. class ){
- Date date = (Date) value;
- return dateFormat.format(date);
- }
- } catch (ParseException e) {}
- return null ;
- }
- }
public class DateTypeConverter extends DefaultTypeConverter{
@Override
public Object convertValue(Map<String, Object> context, Object value,
Class toType) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
try {
if(toType == Date.class){//当字符串向Date类型转换时
String[] params = (String[]) value;// Request.getParameterValues()
return dateFormat.parse(params[0]);
}else if(toType == String.class){//当Date转换成字符串时
Date date = (Date) value;
return dateFormat.format(date);
}
} catch (ParseException e) {}
return null;
}
}
第二种方式是继承org.apache.struts2.util.strutsTypeConverter类,并实现它的两个抽象方法,实现代码如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20DateTypeConverter%20extends%20StrutsTypeConverter%20%7B%0A%09SimpleDateFormat%20dateFormat%20%3D%20new%20SimpleDateFormat(%22yyyyMMdd%22)%3B%0A%09%40Override%0A%09public%20Object%20convertFromString(Map%20context%2C%20String%5B%5D%20value%2C%20Class%20toType)%20%7B%0A%09%09String%5B%5D%20params%20%3D%20(String%5B%5D)%20value%3B%2F%2F%20Request.getParameterValues()%20%0A%09%09try%20%7B%0A%09%09%09return%20dateFormat.parse(params%5B0%5D)%3B%0A%09%09%7D%20catch%20(ParseException%20e)%20%7B%7D%0A%09%09return%20null%3B%0A%09%7D%0A%0A%09%40Override%0A%09public%20String%20convertToString(Map%20context%2C%20Object%20value)%20%7B%0A%09%09Date%20date%20%3D%20(Date)%20value%3B%0A%09%09return%20dateFormat.format(date)%3B%0A%09%7D%0A%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public class DateTypeConverter extends StrutsTypeConverter {
- SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyyMMdd" );
- @Override
- public Object convertFromString(Map context, String[] value, Class toType) {
- String[] params = (String[]) value;
- try {
- return dateFormat.parse(params[ 0 ]);
- } catch (ParseException e) {}
- return null ;
- }
-
- @Override
- public String convertToString(Map context, Object value) {
- Date date = (Date) value;
- return dateFormat.format(date);
- }
- }
public class DateTypeConverter extends StrutsTypeConverter {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
@Override
public Object convertFromString(Map context, String[] value, Class toType) {
String[] params = (String[]) value;// Request.getParameterValues()
try {
return dateFormat.parse(params[0]);
} catch (ParseException e) {}
return null;
}
@Override
public String convertToString(Map context, Object value) {
Date date = (Date) value;
return dateFormat.format(date);
}
}
知识提示: 查找StrutsTypeConverter的源码发现,它本身也继承了DefaultTypeConverter类.StrutsTypeConverter类使用的一种设计模式是模板方法设计模式 ,在http://yulon.iteye.com/admin/blogs/550501 这里有讲到模板方法模式在项目中的应用.
最后 ,配置要使用该转换器的action类
在HelloWorldAction同一包内新建HelloWorldAction-conversion.properties文件.文件名的后半部分是固定不变的
*-conversion.properties,*表示的是对应的Action的简单类名(即不带包名),在该文件里如下定义:
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=birthday%3Dcn.gkit.type.converter.DateTypeConverter%0A" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- birthday = cn .gkit.type.converter.DateTypeConverter
birthday=cn.gkit.type.converter.DateTypeConverter
birthday表示要转换的属性,右边对应一个转换器.
此时访问路径:/struts2.1/test/helloworld.action?birthday=20091220,Struts框架就是使用刚才定义的转换器将String类型转换成java.util.Date类型.
8.2 定义全局类型转换器
全局类型转换器的配置文件名是固定的:xwork-conversion.properties,并将该文件放到src目录,编译后会自动WEB-INF\classes目录下.在该文件里如下定义:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=java.util.Date%3Dcn.gkit.type.converter.DateTypeConverter" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- java.util.Date=cn.gkit.type.converter.DateTypeConverter
java.util.Date=cn.gkit.type.converter.DateTypeConverter
左边定义的是要转换的类型,作用了全部Action类.
注意: 如果同时定义了局部和全局的类型转换器,对于同一个类型,局部会覆盖全局的转换器
相关文章:http://yulon.iteye.com/admin/blogs/551982 (struts2.1两天快速入门(第一天上午))
由于拦截器的重要性,决定将其从(struts2.1两天快速入门第一天下午 抽取出来讲)
本讲将结合模拟用户权限验证展开:判断用户是否有权限请求访问某一模块或页面 .
第九讲、自定义拦截器
9.1 首先定义一个User实体类,如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20User%20implements%20Serializable%20%7B%0A%09private%20String%20username%3B%0A%09private%20String%20password%3B%0A%09public%20String%20getUsername()%20%7B%0A%09%09return%20username%3B%0A%09%7D%0A%09public%20void%20setUsername(String%20username)%20%7B%0A%09%09this.username%20%3D%20username%3B%0A%09%7D%0A%09public%20String%20getPassword()%20%7B%0A%09%09return%20password%3B%0A%09%7D%0A%09public%20void%20setPassword(String%20password)%20%7B%0A%09%09this.password%20%3D%20password%3B%0A%09%7D%0A%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public class User implements Serializable {
- private String username;
- private String password;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this .username = username;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this .password = password;
- }
- }
public class User implements Serializable {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
9.2 编写一个用户登陆的Action类,如下:
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://yulon.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20UserLoginAction%20%7B%0A%09%2F%2F%E6%8E%A5%E6%94%B6%E5%A4%8D%E5%90%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%82%E6%95%B0%2C%E4%B8%8Estruts1.x%E7%9B%B8%E7%B1%BB%E4%BC%BC%2C%E6%AD%A4%E6%97%B6%E8%A1%A8%E5%8D%95%E7%9A%84%E5%85%83%E7%B4%A0%E5%90%8D%E7%A7%B0%0A%09%2F%2F%E5%BA%94%E8%AF%A5%E4%B8%BA%3Auser.username%20%20%20user.password%0A%09private%20User%20user%3B%20%20%0A%09public%20User%20getUser()%20%7B%0A%09%09return%20user%3B%0A%09%7D%0A%09public%20void%20setUser(User%20user)%20%7B%0A%09%09this.user%20%3D%20user%3B%0A%09%7D%0A%09public%20String%20execute()%7B%0A%09%2F%2F%E6%A8%A1%E6%8B%9F%E7%94%A8%E6%88%B7%E7%99%BB%E9%99%86%2C%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%E6%98%AF%E4%BB%8E%E6%95%B0%E6%8D%AE%E5%BA%93%E9%87%8C%E5%8F%96%E7%9A%84%2C%E8%BF%99%E9%87%8C%E5%8F%AA%E6%98%AF%E4%B8%BA%E4%BA%86%E6%96%B9%E4%BE%BF%E6%B5%8B%E8%AF%95%E5%92%8C%E5%AD%A6%E4%B9%A0%09%0A%09if(%22yulon%22.equals(user.getUsername())%26%26%22123456%22.equals(user.getPassword()))%7B%0A%09%09%2F%2F%E4%B8%BA%E4%BA%86%E4%B8%8D%E8%AE%A9%E6%88%91%E4%BB%AC%E7%9C%8B%E5%88%B0%E7%9C%9F%E6%AD%A3%E7%9A%84session%2Cstruts2%E6%A1%86%E6%9E%B6%E5%AF%B9%E5%85%B6%E4%BD%9C%E4%BA%86%E4%B8%80%E5%B1%82%E5%B0%81%E8%A3%85%2C%E7%94%A8%E4%B8%80%E4%B8%AAMap%E5%AF%B9%E8%B1%A1%E6%9D%A5%E5%AD%98%E5%82%A8.%0A%09%09%2F%2FMap%20map%20%3D%20ActionContext.getContext().getSession()%3B%0A%09%09%2F%2Fmap.put(%22user%22%2C%20user)%3B%0A%09%09%2F%2F%E6%8A%8A%E4%B8%A4%E6%AE%B5%E4%BB%A3%E7%A0%81%E5%90%88%E6%88%90%E4%B8%80%E6%AE%B5%2C%E5%B0%B1%E4%B8%8D%E7%94%A8%E5%AF%BC%E5%85%A5Map%E7%B1%BB%0A%09%09ActionContext.getContext().getSession().put(%22user%22%2C%20user)%3B%0A%09%09return%20Action.SUCCESS%3B%20%20%20%2F%2F%E8%BF%94%E5%9B%9E%E5%88%B0%E6%AC%A2%E8%BF%8E%E9%A1%B5%E9%9D%A2%0A%09%20%7D%0A%09%09ActionContext.getContext().put(%22msg%22%2C%20%22%E7%94%A8%E6%88%B7%E7%99%BB%E9%99%86%E5%A4%B1%E8%B4%A5!%22)%3B%0A%09%09%2F%2F%E8%BF%94%E5%9B%9E%E5%88%B0%E7%99%BB%E9%99%86%E9%A1%B5%E9%9D%A2%2Cstruts%E5%AE%9A%E4%B9%89%E4%BA%86%E4%B8%80%E7%B3%BB%E5%88%97%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%B8%B8%E9%87%8F%2C%E6%96%B9%E4%BE%BF%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%2C%E7%BB%9F%E4%B8%80%E7%9A%84%E5%A5%BD%E5%A4%84%0A%09%09return%20Action.LOGIN%3B%20%20%20%0A%09%7D%0A%7D" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
- public class UserLoginAction {
-
-
- private User user;
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this .user = user;
- }
- public String execute(){
-
- if ( "yulon" .equals(user.getUsername())&& "123456" .equals(user.getPassword())){
-
-
-
-
- ActionContext.getContex