struts2工作流程及各种文件详解

转自:http://blog.csdn.net/zjtimef/article/details/12027767



当用户发送一个请求后,web.xml中配置的FilterDispatche(Struts 2核心控制器)就会过滤该请求,FilterDispatcher根据配置,将请求转发给Action。

以下是详解过程:

1、 当Web容器收到 请求(HttpServletRequest),例如http://localhost:8080/Struts 2.0/hello.jsp就是一个请求。

2、 请求被提交到一系列的(主要有三层)过滤器(Filter),如(ActionContextCleanUp)过滤器,然后经过Other filters(SiteMesh ,etc),最后才到达FilterDispatcher,这里是顺序执行的。

3、  FilterDispatcher是控制器的核心,就是mvc的struts2实现控制层(controller)的核心。然后它调用ActionMapper确定请求那个Action,ActionMapper返回一个收集Action详细信息的ActionMaping对象。

4、 FilterDispatcher将控制权委派给ActionProxy,ActionProxy调用配置管理器Configuration Manager(struts.xml),找到需要调用的Action类。例如上一篇的StrutsAction类就是Action类。

5、 接着ActionProxy创建一个ActionInvocation对象,ActionInvocation在调用Action之前会依次根据配置加载Action相关的所有拦截器(Interceptor )

6、  一旦Action执行完毕,ActionInvocation负责根据struts.xml中配置找到对应的返回结果result。

struts2工作流程及各种文件详解

首先用到的是web.xml

  1. <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/JavaEE/web-app_2_5.xsd">  
  7.     <filter>  
  8.         <filter-name>struts 2</filter-name>  
  9.         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>struts 2</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15. </web-app>  
  16. </span>  

最上面是普通的xml文件头,然后是一些引用文件。后面的webapp标签中配置了下面这样一段:

<filter>

    <filter-name>struts2</filter-name>

    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

</filter>

<filter-mapping>

    <filter-name>struts2</filter-name>

    <url-pattern>/*</url-pattern>

            </filter-mapping>

所有过滤器必须实现java.Serlvet.Filter接口,这个接口中含有3个过滤器类必须实现的方法:(该过滤器类的源代码可在struts2包中获得)

  init(FilterConfig):Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。

  doFilter(ServletRequest,ServletResponse,FilterChain):完成实际的过滤操作,当用户请求与过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法,返回响应之前也会调用此方法。FilterChain参数用于访问过滤器链上的下一个过滤器。

在该方法中将调用dispatcher.serviceAction(),该方法如果找到相应的Action,将把用户的请求交给ActionProxy。

  destroy():Servlet容器在销毁过滤器实例前调用该方法,这个方法可以释放Servlet过滤器占用的资源。

过滤器类编写完成后,必须要在web.xml中进行配置,格式如下:

<filter>

    <!--自定义的名称-->

    <filter-name>过滤器名</filter-name>

    <!--自定义的过滤器类,注意,这里要在包下,要加包名-->

    <filter-class>过滤器对应类</filter-class>

  <init-param>

  <!--类中参数名称-->

  <param-name>参数名称</param-name>

  <!--对应参数的值-->

  <param-value>参数值</param-value>

  </init-param>

 </filter>

过滤器必须和特定的URL关联才能发挥作用,过滤器的关联方式有3种:与一个URL资源关联、与一个URL目录下的所有资源关联、与一个Servlet关联。

 与一个URL资源关联:

<filter-mapping>

  <!- -这里与上面配置的名称要相同-->

  <filter-name>过滤器名</filter-name>

  <!- -与该URL资源关联-->

  <url-pattern>xxx.jsp</url-pattern>

</filter-mapping>

 与一个URL目录下的所有资源关联:

<filter-mapping>

  <filter-name>过滤器名</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping>

 与一个Servlet关联:

<filter-mapping>

  <filter-name>过滤器名</filter-name>

  <url-pattern>Servlet名称</url-pattern>

</filter-mapping>


struts.xml文件

  1. <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>  
  6.     <package name="default" extends="struts-default">  
  7.         <action name="struts" class="org.action.StrutsAction">  
  8.             <result name="success">/welcome.jsp</result>  
  9.             <result name="error">/hello.jsp</result>  
  10.         </action>  
  11.     </package>  
  12. </struts>  
  13. </span>  


package
有以下几个常用属性:


name(必选):指定包名,这个名字将作为引用该包的键。注意,包的名字必须是唯一的,在一个struts.xml文件中不能出现两个同名的包。

extends(可选):允许一个包继承一个或多个先前定义的包。

abstract(可选):将其设置为true,可以把一个包定义为抽象的。抽象包不能有action定义,只能作为“父”包被其他包所继承。

namespace(可选):将保存的action配置为不同的名称空间。

看下面这个例子:

  1. <span style="font-size:18px"><package name="default">  
  2.     <action name="foo" class="mypackage.simpleAction">  
  3.         <result name="success">/foo.jsp</result>  
  4.     </action>  
  5.     <action name="bar" class="mypackage.simpleAction">  
  6.         <result name="success">/bar.jsp</result>  
  7.     </action>  
  8. </package>  
  9. <package name="mypackage1" namespace="/">  
  10.     <action name="moo" class="mypackage.simpleAction">  
  11.         <result name="success">/moo.jsp</result>  
  12.     </action>  
  13. </package>  
  14. <package name="mypackage2" namespace="/barspace">  
  15.     <action name="bar" class="mypackage.simpleAction">  
  16.         <result name="success">/bar.jsp</result>  
  17.     </action>  
  18. </package></span>  


Action元素

当一个请求匹配到某个Action名字时,框架就使用这个映射来确定如何处理请求。

<actionname="struts" class="org.action.StrutsAction">

  <resultname="success">/welcome.jsp</result>

  <resultname="error">/hello.jsp</result>

</action>


在上面代码中,当一个请求映射到struts时,就会执行该Action配置的class属性对应的Action类,然后根据Action类的返回值决定跳转的方向。其实一个Action类中不一定只能有execute()方法。如果一个请求要调用Action类中的其他方法,就需要在Action配置中加以配置。例如,如果在org.action.StrutsAction中有另外一个方法为:

public String find()throws Exception{return SUCCESS;}

那么如果想要调用这个方法,就必须在Action中配置method属性,配置方法为:

<! - - name值是用来和请求匹配的- - >

<actionname="find" class="org.action.StrutsAction"method="find">

  <resultname="success">/welcome.jsp</result>

  <resultname="error">/hello.jsp</result>

</action>


result元素

一个result代表一个可能的输出。当Action类中的方法执行完成时,返回一个字符串类型的结果代码,框架根据这个结果代码选择对应的result,向用户输出。

<result name="逻辑视图名" type="视图结果类型"/>

           <param name ="参数名">参数值</param>

</result>

param中的name属性有两个值:

  location:指定逻辑视图。

  parse:是否允许在实际视图名中使用OGNL表达式,参数默认为true


result中的name属性有如下值:

success:表示请求处理成功,该值也是默认值。

error:表示请求处理失败。

none:表示请求处理完成后不跳转到任何页面。

input:表示输入时如果验证失败应该跳转到什么地方(关于验证后面会介绍)。

login:表示登录失败后跳转的目标。

type(非默认类型)属性支持的结果类型有以下几种:

chain:用来处理Action链。

chart:用来整合JFreeChart的结果类型。

dispatcher:用来转向页面,通常处理JSP,该类型也为默认类型。

freemarker:处理FreeMarker模板。

httpheader:控制特殊HTTP行为的结果类型。

jasper:用于JasperReports整合的结果类型。

jsfJSF整合的结果类型。

redirect:重定向到一个URL

redirect-action:重定向到一个Action

stream:向浏览器发送InputStream对象,通常用来处理文件下载,还可用于返回AJAX数据。

tiles:与Tiles整合的结果类型。

velocity:处理Velocity模板。

xslt:处理XML/XLST模板。

plaintext:显示原始文件内容,如文件源代码。

其中,最常用的类型就是dispatcherredirect-actiondispatcher类型是默认类型,通常不写,主要用于与JSP页面整合。redirect-action类型用于当一个Action处理结束后,直接将请求重定向到另一个Action如下列配置:

<actionname="struts" class="org.action.StrutsAction" >

  <resultname="success">/welcome.jsp</result>

  <resultname="error">/hello.jsp</result>

</action>

<actionname="login" class="org.action.StrutsAction">

  <result name="success"type="redirect-action">struts</result>

</action>

ActionSupport

下面是ActionSupport类所实现的接口:

  1. <span style="font-size:18px">public class ActionSupport implements Action, Validateable, ValidationAware,  
  2.         TextProvider, LocaleProvider,Serializable {  
  3. }  
  4. Action接口同样位于com.opensymphony.xwork2包,定义了一些常量和一个execute()方法。  
  5. public interface Action {  
  6.     public static final String SUCCESS="success";  
  7.     public static final String NONE="none";  
  8.         public static final String ERROR="error";  
  9.         public static final String INPUT="input";  
  10.     public static final String LOGIN="login";  
  11.         public String execute() throws Exception;  
  12. }  
  13. </span>  
Action类

  1. <span style="font-size:18px">package org.action;  
  2. import java.util.Map;  
  3. import com.opensymphony.xwork2.ActionContext;  
  4. import com.opensymphony.xwork2.ActionSupport;  
  5. public class StrutsAction extends ActionSupport{  
  6.     private String name;  
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.     public void setName(String name) {  
  11.         this.name=name;  
  12.     }  
  13.     public String execute() throws Exception {  
  14.         if(!name.equals("HelloWorld")){  
  15.             Map request=(Map)ActionContext.getContext().get("request");  
  16.             request.put("name",getName());  
  17.             return "success";  
  18.         }else{  
  19.             return "error";  
  20.         }  
  21.     }  
  22. }  
  23. </span>  


Action类继承了ActionSupport类,所以可以看出,在execute的返回值中,其代码可以改为:

public Stringexecute() throws Exception {

  if(!name.equals("HelloWorld")){

  Map request=(Map)ActionContext.getContext().get("request");

  request.put("name",getName());

  returnSUCCESS;

  }else{

  returnERROR;

  }

}







上一篇:myeclipse10中有几处bug


下一篇:Struts 2 简介 Struts2的基本流程