搭建Struts2环境时,我们一般需要做以下几个步骤的工作:
1》找到开发Struts2应用需要使用到的jar文件.
不同的应用需要的JAR包是不同的。下面给出了开发Struts 2程序最少需要的JAR。
struts2-core-2.x.x.jar :Struts 2框架的核心类库
xwork-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.1.x.jar :ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。
commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后必须加入此文件
2》编写Struts2的配置文件(默认首先为空)
<?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>
3》在web.xml中加入Struts2 MVC框架启动配置
<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完成初始化操作。
注意:struts2读取到struts.xml的内容后,以javabean形式存放在内存中,以后struts2对用户的每次请求处理将使用内存中的数据,而不是每次都读取struts.xml文件
2、第一个strut2应用程序HelloWorld
struts.xml配置
<?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="itcast" extends="struts-default" namespace="/test" > <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute" > <result name="success">/WEB-INF/page/hello.jsp</result> </action> </package> </struts>
说明:extends=“struts-default”,struts-default.xml配置文件可在struts2-core-2.1.6.jar包中找到。
<package name="struts-default" abstract="true> </package>
struts-default包声明为abstract,这说明该包只能被用来继承,而其中不能有action配置.
创建相应的java类
package cn.itcast.action; public class HelloWorldAction { private String message; public String execute() { message = "第一个struts2应用"; return "success"; } public String getMessage() { return message; } }
创建hello.jsp文件
<body> ${message } </body>
在Hello.jsp中通过el表达式来取得message的值,但是在HelloWorldAction.java中并没有显示的将该属性值放置到request,session,application中,实现原理将在后面讲解。 但是必须要在Action中增加想要得到属性的get方法,el表达式中的'message’字符串取得是Action属性中getXXX()方法的方法名后面部分,所以el表达式中的字符串可以与Action中属性不一致,只要跟getXXX一致就可以了。
3、Action名称的搜索顺序
(1)获得请求路径的URI,例如url是:http://server/struts2/path1/path2/path3/test.action
(2)首先寻找namespace为/path1/path2/path3的package,如果存在这个package,则在这个package中寻找名字为test的action,如果不存在这个package则转步骤3;
(3)寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为test的action,如果不存在这个package,则转步骤4;
(4)寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找名字为test的action,如果仍然不存在这个package,就去默认的namaspace的package下面去找名字为test的action(默认的命名空间为空字符串"" ),如果还是找不到,页面提示找不到action。
4、Action配置中的各项默认值
<package name="itcast" namespace="/test" extends="struts-default"> <action name="addUI" > <result>/WEB-INF/page/hello.jsp</result> </action> </package>
如果一个用户的请求不需要经过Action类的话,我们可以用上面配置的方法直接将请求转发给相关jsp界面。(需要了解下面action配置的默认项)
1>如果没有为action指定class,默认是ActionSupport。
2>如果没有为action指定method,默认执行action中的execute() 方法。
3>如果没有指定result的name属性,默认值为success。
5、Action中result的各种转发类型
(1)第一种:即最简单的分发的方式,类似于struts1中的dispatch方式
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute" > <result name="success">/WEB-INF/page/hello.jsp</result> </action>
(2)第二种:浏览器重定向方式
相关Action中java代码
package cn.itcast.action; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class HelloWorldAction { private String message; private String username; public String getMessage() { return message; } public String execute() throws Exception { message = "第一个struts2应用"; this.username = URLEncoder.encode("黎明", "UTF-8"); return "success"; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
struts.xml相关配置
<action name="redirect" class="cn.itcast.action.HelloWorldAction" method="execute" > <result name="success" type="redirect" >/employyerAdd.jsp?username=${username}</result> </action>
使用此种方式,需要在result标签中指定一下type=redirect,同时可以传值,可使用类似于el表达式的方式,{}中的值依然以该属性的getXXX方法为准.
jsp文件
<body> <!-- 乱码 --> ${param.username } <!-- 正常显示 --> <%= new String(request.getParameter("username").getBytes("iso8859-1"),"UTF-8") %> <form action=""> 姓名:<input name="xxx"> </form> </body>
当username的值为中文,并使用url传值方式传递属性值会出现中文乱码问题,所以在java类中需要对中文指定以utf-8字符编码进行传值,而在jsp中需要以iso8859-1的方式得到字符串的字节流然后以utf-8的方式显示。
(3)从一个Action重定向到另外一个Action
struts.xml相关配置
<package name="itcast" namespace="/test" extends="struts-default"> <action name="redirect" class="cn.itcast.action.HelloWorldAction" method="execute"> <result name="success" type="redirect"> /employyerAdd.jsp?username=${username} </result> </action> <action name="redirectAction" class="cn.itcast.action.HelloWorldAction" method="execute"> <result name="success" type="redirectAction">redirect</result> </action> </package>
当我们访问redirectAction请求时,会重定向到redirect请求,而该请求又重新定向到了employyer.jsp,经过了两次重定向的请求。
对于上面这种Action重定向的方式,要定向的action跟访问的action 在同一个package下,如果在两个不同的package下怎么配置?
可采用如下配置方法完成:
<package name="itcast" namespace="/test" extends="struts-default"> <action name="redirectAction" class="cn.itcast.action.HelloWorldAction" method="execute"> <result name="success" type="redirectAction"> <param name="namespace">/a/b/c</param> <param name="actionName">xxx</param> </result> </action> </package> <package name="other" namespace="/a/b" extends="struts-default"> <action name="xxx"> <result>/index.jsp</result> </action> </package>
当访问redirectAction时,struts2会自动根据result标签中制定的名称,寻找相关的namespace名称,以及action名称。
在redirectAction的result标签中的namespace属性,故意多写了一个/c,这样也是可以访问的,是想说明前面说过的action搜索顺序知识。
(4)type="plaintext"
plaintext:显示原始文件内容,例如:当我们需要原样显示jsp文件源代码 的时候,我们可以使用此类型。
<result name="source" type="plainText "> <param name="location">/xxx.jsp</param> <param name="charSet">UTF-8</param><!-- 指定读取文件的编码 --> </result>在result中还可以使用${属性名}表达式访问action中的属性,表达式里的属性名对应action中的属性。如下:
<result type="redirect">view.jsp?id=${id}</result>
(5)struts2的全局跳转
【1】package范围内的全局跳转
<struts> <package name="itcast" namespace="/test" extends="struts-default"> <global-results> <result name="message">/MyJsp.jsp</result> </global-results> <action .............. > <result>/xxx.jsp</result> </action> <action name="manager" class="cn.itcast.action.HelloWorldAction" method="add"> </action> </package> </struts>
上述 <global-results>标签中的值负责跳转,因标签放到了package标签下面 所以此跳转只负责此package下面的,所以访问:http://localhost/application/test/manager.acation,会跳转到/MyJsp.jsp下面
【2】全局范围内的跳转
<struts> <package name="base" extends="struts-default" > <global-results> <result name="message1">/WEB-INF/page/hello.jsp</result> </global-results> </package> <package name="itcast" namespace="/test" extends="base"> <global-results> <result name="message">/MyJsp.jsp</result> </global-results> <action .............. > <result>/xxx.jsp</result> </action> <action name="manager" class="cn.itcast.action.HelloWorldAction" method="add"> </action> </package> </struts> 对于全局范围内的跳转,将该配置项放置于struts标签下,与package标签同级。对于其他package下的action如果要使用该全局跳转则必须要继承该package。如果package级别和全局级别中都有符合条件的跳转,则struts2自动选择该action所在包下的跳转