[关闭]
@liayun 2016-10-01T05:38:31.000000Z 字数 12519 阅读 1811

Struts2框架进阶(一)

Struts2框架学习


Struts2框架入门之后,我们就要踏上Struts2框架漫漫的进阶之路了。我们以Struts2框架入门中的案例开始吧!

Struts2框架中Action名称的搜索顺序

假设某用户的请求路径的URL是http://localhost:8080/Struts2/path1/path2/path3/test.action,那么Struts2框架是怎么搜索到相应的Action来处理用户的请求呢?答案为:

  1. 首先寻找namespace为/path1/path2/path3的package,不存在这个package则转步骤2,如果存在这个package,则在这个package中寻找名字为test的action,当在该package下找不到action时就会直接跑到默认namespace里面寻找,找不到该action,页面提示找不到action;
  2. 寻找namespace为/path1/path2的package,如果不存在这个package,则转步骤3,如果存在这个package,则在这个package中寻找名字为test的action,当在该package下找不到action时就会直接跑到默认namespace里面寻找,找不到该action,页面提示找不到action;
  3. 寻找namespace为/path1的package,如果不存在这个package,转到步骤4,如果存在这个package,则在这个package中寻找名字为test的action,如果仍然不存在这个package,就去默认的namaspace的package下面去找名字为test的action(默认的命名空间为空字符串"" ),如果还是找不到,页面提示找不到action。
  4. 寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为test的action,如果仍然不存在这个package或者在package中找不到action,就去默认的namaspace的package下面去找,如果还是找不到,页面提示找不到action。

我们将Struts2框架入门案例中的struts.xml配置文件修改成这样:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/test" extends="struts-default">
  7. </package>
  8. <package name="it" extends="struts-default">
  9. <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
  10. <result name="success">/WEB-INF/page/hello.jsp</result>
  11. </action>
  12. </package>
  13. </struts>

这样,当我们在浏览器中输入URL地址,如http://localhost:8080/Struts2/test/sadsa/dsadfs/233432/helloworld.action时,依然会看到这样的结果:
记得插图

在struts.xml中配置Action

对于Struts2框架入门案例中的struts.xml配置文件中的这段代码:

  1. <package name="itcast" namespace="/test" extends="struts-default">
  2. <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
  3. <result name="success">/WEB-INF/page/hello.jsp</result>
  4. </action>
  5. </package>

在Struts1中,通过path属性指定访问该action的URL路径。但在Struts2中,情况就不是这样的了,访问Struts2中的action的URL路径由两部份组成:包的命名空间+action的名称,例如访问上面例子中名为helloworld的Action的URL路径为:/test/helloworld (注意:完整路径为:http://localhost:端口/内容路径/test/helloworld.action)。
Action配置中的各项默认值:

  1. 如果没有为action指定class,默认是ActionSupport
  2. 如果没有为action指定method,默认执行action中的execute()方法
  3. 如果没有为action指定name属性,默认值是success

例如我们在Struts2框架入门案例中的struts.xml配置文件中配置如下Action:

  1. <action name="addUI">
  2. <result>/WEB-INF/page/employeeAdd.jsp</result>
  3. </action>

接着在WEB-INF/page/目录下创建employeeAdd.jsp页面,该页面的内容可以写为:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. <form action="/xxx">
  11. 姓名:<input type="text" name="xxx">
  12. </form>
  13. </body>
  14. </html>

这样,当我们通过浏览器访问http://localhost:8080/Struts2/test/addUI.action该地址时,会跳转到employeeAdd.jsp页面。

在struts.xml中配置Action的result

试看下面的这样一段代码:

  1. <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
  2. <result name="success">/WEB-INF/page/hello.jsp</result>
  3. </action>

result配置类似于Struts1中的forward,但Struts2中提供了多种结果类型,如:dispatcher(默认值)(对应Struts1中的内部请求转发)、redirect、redirectAction、plainText。
下面我们就要来详讲Struts2中提供的多种结果类型。

dispatcher

dispatcher这种结果类型就是Struts2中默认的结果类型,对应Struts1中的内部请求转发,如:

  1. <action path="/control/employee/addUI" ... >
  2. <forward name="add">/index.jsp</forward> <!-- 内部转发使用这种方式,对应Struts2中的dispatcher -->
  3. </action>

没什么好讲的。

redirect

浏览器重定向就是使用redirect这种结果类型。在Struts1中的浏览器重定向是这样写的:

  1. <action path="/control/employee/addUI" ... >
  2. <forward name="add" redirect="true">/index.jsp</forward> <!--浏览器重定向使用这种方式-->
  3. </action>

在Struts2中若要实现浏览器重定向,则必定要使用redirect这种结果类型。我们在Struts2框架入门案例中的struts.xml配置文件中配置如下Action:

  1. <action name="redirect">
  2. <result type="redirect">/employeeAdd.jsp</result>
  3. </action>

此时struts.xml配置文件的内容就为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/control/employee" extends="struts-default">
  7. <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
  8. <result name="success">/WEB-INF/page/hello.jsp</result>
  9. </action>
  10. <action name="addUI">
  11. <result>/WEB-INF/page/employeeAdd.jsp</result>
  12. </action>
  13. <action name="redirect">
  14. <result type="redirect">/employeeAdd.jsp</result>
  15. </action>
  16. </package>
  17. </struts>

由于用户是无法访问到WEB-INF中的文件的,所以重定向的时候不能重定向到WEB-INF中的jsp中,所以我们要把employeeAdd.jsp这个页面移到WebRoot根目录下。
这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirect.action该地址时,浏览器会重定向到employeeAdd.jsp页面。
有时我们希望浏览器重定向到某个页面(如employeeAdd.jsp页面)时,传递一个参数(如用户名)进去。那我们应该怎么办呢?
我们先将HelloWorldAction类的代码修改为:

  1. public class HelloWorldAction {
  2. private String msg;
  3. private String username;
  4. public String getMessage() {
  5. return msg;
  6. }
  7. public String getUsername() {
  8. return username;
  9. }
  10. public void setUsername(String username) {
  11. this.username = username;
  12. }
  13. public String execute() {
  14. this.username = "李阿昀";
  15. this.msg = "我的第一个struts2应用";
  16. return "success";
  17. }
  18. }

由于在result中可以使用${属性名}表达式访问action中的属性,表达式里的属性名对应action中的属性,所以我们可以这样编写代码:

  1. <result type="redirect">/view.jsp?id=${id }</result>

那么,此时struts.xml配置文件的内容就应改为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/control/employee" extends="struts-default">
  7. <action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
  8. <result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
  9. </action>
  10. <action name="addUI">
  11. <result>/WEB-INF/page/employeeAdd.jsp</result>
  12. </action>
  13. <action name="redirect">
  14. <result type="redirect">/employeeAdd.jsp</result>
  15. </action>
  16. </package>
  17. </struts>

接下来,我们就要在employeeAdd.jsp中使用从URL中传过来的参数username${param.username }

  1. <%@page import="java.net.URLDecoder"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. ${param.username }
  12. <form action="/xxx">
  13. 姓名:<input type="text" name="xxx">
  14. </form>
  15. </body>
  16. </html>

这时,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/list.action该地址,发现浏览器中URL以及jsp页面出现乱码。原因:tomcat接收到来自URL的用UTF-8编码后的字符串,会使用ISO8859-1进行编码(注意tomcat8内部使用的是UTF-8进行编码的,所以无须多此一举),所以出现乱码。解决方法:以get方式提交过来的中文参数,先得到ISO8859-1的二进制数组,再转成字符串。这样在employeeAdd.jsp页面中,要显示用户名,就要换成这句代码:

  1. <%= URLDecoder.decode(new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8"), "UTF-8") %>

除此之外,HelloWorldAction类的代码还应修改为:

  1. public class HelloWorldAction {
  2. private String msg;
  3. private String username;
  4. public String getMessage() {
  5. return msg;
  6. }
  7. public String getUsername() {
  8. return username;
  9. }
  10. public void setUsername(String username) {
  11. this.username = username;
  12. }
  13. public String execute() throws Exception { // execute()的返回值必须是String类型
  14. this.username = URLEncoder.encode("李阿昀", "UTF-8"); // 不能再URL中直接传字符串,所以应该编码
  15. this.msg = "我的第一个struts2应用";
  16. return "success";
  17. }
  18. }

至此,浏览器中URL以及jsp页面出现的中文乱码问题就得以解决了。

redirectAction

重定向到某个Action就要使用redirectAction这种结果类型。
如果重定向的action在同一个包下:
例如,Struts2框架入门案例中的struts.xml配置文件若为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/control/employee" extends="struts-default">
  7. <action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
  8. <result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
  9. </action>
  10. <action name="addUI">
  11. <result>/WEB-INF/page/employeeAdd.jsp</result>
  12. </action>
  13. <action name="redirect">
  14. <result type="redirect">/employeeAdd.jsp</result>
  15. </action>
  16. <action name="redirectAction">
  17. <result type="redirectAction">/list</result>
  18. </action>
  19. </package>
  20. </struts>

这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirectAction.action该地址时,经过两次重定向之后就到了employeeAdd.jsp页面中。
如果重定向的action在别的命名空间下:
例如,Struts2框架入门案例中的struts.xml配置文件若为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/control/employee" extends="struts-default">
  7. <action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
  8. <result name="success" type="redirect">/employeeAdd.jsp?username=${username }</result>
  9. </action>
  10. <action name="addUI">
  11. <result>/WEB-INF/page/employeeAdd.jsp</result>
  12. </action>
  13. <action name="redirect">
  14. <result type="redirect">/employeeAdd.jsp</result>
  15. </action>
  16. <action name="redirectAction">
  17. <result type="redirectAction">
  18. <param name="actionName">xxx</param> <!-- 为redirectAction这个类型所对应的Java类的属性注入值 -->
  19. <param name="namespace">/control/department</param>
  20. </result>
  21. </action>
  22. </package>
  23. <package name="other" namespace="/control/department" extends="struts-default">
  24. <action name="xxx">
  25. <result>/WEB-INF/page/hello.jsp</result>
  26. </action>
  27. </package>
  28. </struts>

这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/redirectAction.action该地址时,经过一次重定向和一次内部请求转发之后就能看到employeeAdd.jsp页面中的内容了。

plainText

plainText显示原始文件内容,例如:当我们需要原样显示jsp文件源码的时候,可以使用该类型。
我们可以在Struts2框架入门案例中的struts.xml配置文件配置这样一个Action:

  1. <action name="plainText">
  2. <result type="plainText">
  3. <param name="location">/index.jsp</param> <!-- 指定请求路径 -->
  4. <param name="charSet">UTF-8</param> <!-- 指定读取文件的编码 -->
  5. </result>
  6. </action>

接下来,我们就要在WebRoot根目录下创建index.jsp页面了。

  1. <%@page import="java.util.Date"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%= new Date() %> 中国
  12. </body>
  13. </html>

这样,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/plainText.action该地址时,就能看到index.jsp文件的源码了。

为Action的属性注入值

Struts2为Actoin中的属性提供了依赖注入功能,在Struts2的配置文件中,我们可以很方便地为Action的属性注入值。注意:属性必须提供setter方法
我们先将HelloWorldAction类的代码修改为:

  1. public class HelloWorldAction {
  2. private String savepath;
  3. public String getSavepath() {
  4. return savepath;
  5. }
  6. public void setSavepath(String savepath) {
  7. this.savepath = savepath;
  8. }
  9. public String execute() { // execute()的返回值必须是String类型
  10. return "success";
  11. }
  12. }

再将struts.xml配置文件的内容置为:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6. <package name="itcast" namespace="/control/employee" extends="struts-default">
  7. <action name="list" class="cn.itcast.action.HelloWorldAction" method="execute">
  8. <param name="savepath">/images</param>
  9. <result name="success">/WEB-INF/page/message.jsp</result>
  10. </action>
  11. </package>
  12. </struts>

上面通过<param>结点为Action的savepath属性注入“/images”。
最后我们要在WEB-INF/page/目录下创建message.jsp页面。

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. 结果<br/>
  11. ${savepath }
  12. </body>
  13. </html>

提示:可在message.jsp页面中使用EL表达式:${savePath }
这样,,当我们通过浏览器访问http://localhost:8080/Struts2/control/employee/list.action该地址时,就能看到如下结果:
要记得插图

指定需要Struts2处理的请求后缀

默认处理的后缀是可以通过常量"struts.action.extension"进行修改的,如下配置Struts2只处理以.do为后缀的请求路径:

  1. <struts>
  2. <constant name="struts.action.extension" value="do"/>
  3. </struts>

如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。如:

  1. <constant name="struts.action.extension" value="do,action"/>

定义常量

常量可以在struts.xml或struts.properties中配置,建议在struts.xml中配置,两种配置方式如下:

通常,Struts2按如下搜索顺序加载Struts2常量:

  1. struts-default.xml
  2. struts-plugin.xml
  3. struts.xml
  4. struts.properties
  5. web.xml

如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值。

常用的常量

Struts2常用的常量有:

  1. <constant name="struts.i18n.encoding" value="UTF-8"/>

指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker、velocity的输出。

  1. <constant name="struts.action.extension" value="do"/>

该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。

  1. <constant name="struts.serve.static.browserCache" value="false"/>

设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭。

  1. <constant name="struts.configuration.xml.reload" value="true"/>

当Struts2的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开。修改了struts.xml,不需重启服务器。

  1. <constant name="struts.devMode" value="true" />

开发模式下使用,这样可以打印出更详细的错误信息。

  1. <constant name="struts.ui.theme" value="simple" />

默认的视图主题。

  1. <constant name="struts.objectFactory" value="spring" />

与Spring集成时,指定由Spring负责action对象的创建。

  1. <constant name="struts.enable.DynamicMethodInvocation" value="false"/>

该属性设置Struts2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。

  1. <constant name="struts.multipart.maxSize" value="10701096">

上传文件()的大小限制。

Struts2的处理流程

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注