您的位置:首页 > 编程语言 > Java开发

Struts2系统学习(3)Action深入

2015-11-12 18:00 295 查看

3. Action深入

3.1 Action类

  在Struts2中,一个Action类代表一次请求或调用,每个请求的动作都对应于一个相应的Action类,一个Action类是一个独立的工作单元。

  也就是说,用户的每次请求,都会转到一个相应的Action类里面,由这个Action类来进行处理,因此说一个Action类代表了用户的一次请求或调用。

  并且每个用户的请求都会创建独立的action对象,因此action是线程安全的。

3.2 Action名称的搜索顺序

  案例一:假设请求路径的URL为:http://server/app/path1/path2/path3/test.action

首先寻找namespace为/path1/path2/path3的package,如果不存在这个package则执行步骤3;如果存在这个package,则在这个package中寻找名字为test的action,当在该package下寻找不到action时就会直接跑到默认namaspace的package里面去寻找action(默认的命名空间为空字符串“” ),如果在默认namaspace的package里面还寻找不到该action,页面提示找不到action。

寻找namespace为/path1/path2的package,如果不存在这个package,则转至步骤4;如果存在这个package,则在这个package中寻找名字为test的action,当在该package中寻找不到action时就会直接跑到默认namaspace的package里面去找名字为test的action,在默认namaspace的package里面还寻找不到该action,页面提示找不到action。

寻找namespace为/path1的package,如果不存在这个package则执行步骤5;如果存在这个package,则在这个package中寻找名字为test的action,当在该package中寻找不到action时就会直接跑到默认namaspace的package里面去找名字为test的action,在默认namaspace的package里面还寻找不到该action,页面提示找不到action。

寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为test的action,当在package中寻找不到action或者不存在这个package时,都会去默认namaspace的package里面寻找action,如果还是找不到,页面提示找不到action。

案例二:

如下配置:

<struts>
<package name="day01" namespace="/day01" extends="struts-default">
<action name="helloworld" class="com.markliu.test.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/pages/sayhello.jsp</result>
</action>
</package>
</struts>


  可通过 http://ip:port/app/day01/helloworld.action访问该action,也可以通过:http://ip:port/app/day01/kjhsd/asd/helloworld.action访问。

  案例三:

如下配置:

<package name="day01" namespace="/day01" extends="struts-default">
</package>
<package name="day02" namespace="" extends="struts-default">
<action name="helloworld" class="com.markliu.test.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/pages/sayhello.jsp</result>
</action>
</package>


  可通过 http://ip:port/app/day01/kjhsd/asd/helloworld.action访问该action。在/day01命名空间下没有找到helloworld.action,则直接到默认namaspace的package里面寻找action。

3.3 Action配置中的各项默认值

<package name="day01-2" namespace="/day01" extends="struts-default">
<action name="helloworld">
<result>/WEB-INF/pages/sayhello.jsp</result>
</action>
</package>


(1)如果没有为action指定class,默认com.opensymphony.xwork2.ActionSupport。

(2)如果没有为action指定method,默认执行action中的execute() 方法。

(3)如果没有指定result的name属性,默认值为success。

  查看ActionSupport类,会发现默认存在execute方法,且返回success:

public String execute() throws Exception {
// public static final String SUCCESS = "success";
return SUCCESS;
}


3.4 Action中result的各种转发类型

  result配置类似于struts1中的forward,但struts2中提供了多种结果类型,常用的类型有: dispatcher(默认值:内部转发)、 redirect 、 redirectAction 、 plainText。

3.4.1 dispatcher(default)转发类型

默认为服务器内部请求转发。

<action name="helloworld" class="com.markliu.test.HelloWorldAction">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>


3.4.2 redirect 转发类型

  注意请求重定向的视图不能放在/WEB-INF/目录下。

  在result中还可以使用${属性名}表达式(OGNL表达式)访问action中的属性,表达式里的属性名对应action中的属性(getter)。如下:

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


  注意:如果username为中文,会出现中文乱码,需要进行URLEncode进行编码。

  (1)在action中为username中文编码

public String execute() throws Exception {
this.username = URLEncoder.encode("Sunny中文", "UTF-8");
return SUCCESS;
}


  (2)浏览器访问该action,地址栏显示编码后的地址:

http://localhost:8080/Struts2/pages/day02/useredit.jsp?username=Sunny%E5%88%98%E5%BA%86

  (3)在显示的视图页面中获取请求参数,并进行解码:

${param.username }


  由于在jsp的头部设置了编码的格式,所以会自动按照UTF-8解码。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>


3.4.3 redirectAction转发类型

如果重定向的action中同一个包下:

<result type="redirectAction">重定向action名称</result>


如果重定向的action在别的命名空间下:

<result type="redirectAction">
<param name="actionName">重定向action名称</param>
<param name="namespace">重定向action所在包名</param>
</result>


在struts2-core-2.3.24.1.jar包下面的struts-default.xml文件中,对struts-default包定义中存在下面对result-type结果视图类型的定义:

<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
<result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>


  其中就包含dispatcher,redirect,redirectAction,plainText四种result转发类型的定义,分别对应一个java类。打开redirectAction对应的java类ServletActionRedirectResult:

存在如下属性:

protected String actionName;
protected String namespace;
protected String method;


  所以设置:

<param name="actionName">重定向action名称</param>
<param name="namespace">/重定向action包名</param>
<param name="method">execute</param>


  实际就是为ServletActionRedirectResult对象注入属性值:setNamespace和setActionName

3.4.4 plainText转发类型

  plainText:显示原始文件内容,例如:当我们需要原样显示jsp文件源代码的时候,我们可以使用此类型。

按照上面的方法找到定义plainText的类:PlainTextResult,需要设置两个属性:

  ·location (default): 作为plain text显示的jsp、html等文件的路径

  ·charSet (optional): 设置响应的编码格式(eg. Content-Type=text/plain; charset=UTF-8) ,并且设置读取该文件所采用的格式。如果不设置 charSet ,Tomcat读取该文件的时候采用系统默认的编码格式(eg.GBK),会出现中文乱码!

<action name="displayJspRawContent" >
<result type="plainText">/myJspFile.jsp</result>
</action>


  一般采用下面的方式:

<action name="displayJspRawContent" >
<result type="plainText">
<param name="location">/myJspFile.jsp</param>
<param name="charSet">UTF-8</param>
</result>
</action>


3.5 多个Action共享一个视图 — 全局result配置

  当多个action中都使用到了相同视图,这时我们应该把result定义为全局视图。struts1中提供了全局forward,struts2中也提供了相似功能:

(1) 当全局视图位于同一个package下:

<package name="day02" namespace="/day02" extends="struts-default">
<!-- 全局视图 -->
<global-results>
<result name="global-message">/WEB-INF/pages/global/message.jsp</result>
</global-results>
<action name="globalresults" class="com.markliu.UserEditAction" method="global">
</action>
</package>


  其中UserEditAction的global方法返回global-message

(2) 当全局视图位于不同的package下:

应用package的继承功能实现:

<package name="base" extends="struts-default">
<global-results>
<result name="global-message">/WEB-INF/pages/global/message.jsp</result>
</global-results>
</package>
<package name="day02" namespace="/day02" extends="base">
<action name="global-results" class="com.markliu.UserEditAction" method="global">
</action>
</package>


  当访问/day02/global-results时,gloal函数返回global-message,当前包中没有找到对应的result,则去父包base中找。

3.6 为Action的属性注入值

  Struts2为Action中的属性提供了依赖注入功能,在struts2的配置文件中,我们可以很方便地为Action中的属性注入值。注意:属性必须提供setter方法。

package com.markliu.test;
import java.net.URLEncoder;
import com.opensymphony.xwork2.Action;
public class UserEditAction implements Action {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}


<action name="action-inject" class="com.markliu.test.UserEditAction" >
<param name="id">12</param>
<result name="success">/WEB-INF/pages/day02/inject.jsp</result>
</action>


  上面通过节点为action的id属性注入12。

3.7 指定需要Struts 2处理的请求后缀

  前面我们都是默认使用.action后缀访问Action。其实默认后缀是可以通过常量”struts.action.extension“进行修改的,例如:我们可以配置Struts 2只处理以.do为后缀的请求路径:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.action.extension" value="do"/>
</struts>


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

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


  注意:修改之后,访问的.do或.go不能省略!

3.8 细说常量定义

3.8.1 常量的配置方法和顺序

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

在struts.xml文件中配置常量

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


  在struts.properties中配置常量

struts.action.extension=do


  因为常量可以在多个配置文件中进行定义,struts2加载常量的顺序:

struts-default.xml

struts-plugin.xml

struts.xml

struts.properties

web.xml

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

3.8.2 常用的常量介绍

<!-- 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出,i18n表示国际化 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 -->
<constant name="struts.action.extension" value="do"/>
<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false"/>
<!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.configuration.xml.reload" value="true"/>
<!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->
<constant name="struts.devMode" value="true" />
<!-- 默认的视图主题 -->
<constant name="struts.ui.theme" value="simple" />
<!– 与spring集成时,指定由spring负责action对象的创建 -->
<constant name="struts.objectFactory" value="spring" />
<!–该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<!--上传文件的大小限制-->
<constant name="struts.multipart.maxSize" value=“10701096"/>


转载请注明出处:http://blog.csdn.net/mark_lq/article/details/49801945
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: