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

来源:互联网 发布:mac word 繁简转换 编辑:程序博客网 时间:2024/06/18 00:37

当用户发送一个请求后,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。


首先用到的是web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/JavaEE/web-app_2_5.xsd"> <filter><filter-name>struts 2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class></filter><filter-mapping><filter-name>struts 2</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>

最上面是普通的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文件

<?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="default" extends="struts-default"><action name="struts" class="org.action.StrutsAction"><result name="success">/welcome.jsp</result><result name="error">/hello.jsp</result></action></package></struts>


       package
有以下几个常用属性:


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

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

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

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

看下面这个例子:

<package name="default"><action name="foo" class="mypackage.simpleAction"><result name="success">/foo.jsp</result></action><action name="bar" class="mypackage.simpleAction"><result name="success">/bar.jsp</result></action></package><package name="mypackage1" namespace="/"><action name="moo" class="mypackage.simpleAction"><result name="success">/moo.jsp</result></action></package><package name="mypackage2" namespace="/barspace"><action name="bar" class="mypackage.simpleAction"><result name="success">/bar.jsp</result></action></package>


Action元素

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

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

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

  <result name="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值是用来和请求匹配的- - >

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

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

  <result name="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(非默认类型)属性支持的结果类型有以下几种:

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

redirect-action:重定向到一个Action

chain:用来处理Action链。

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

freemarker:处理FreeMarker模板。

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

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

jsfJSF整合的结果类型。

redirect:重定向到一个URL


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

<action name="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类(该类实现Action、Validatable接口,由Action类继承

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

public class ActionSupport implements Action, Validateable, ValidationAware,TextProvider, LocaleProvider,Serializable {}Action接口同样位于com.opensymphony.xwork2包,定义了一些常量和一个execute()方法。public interface Action {public static final String SUCCESS="success";public static final String NONE="none";    public static final String ERROR="error";    public static final String INPUT="input";public static final String LOGIN="login";    public String execute() throws Exception;}
         Action类继承ActionSupport

package org.action;import java.util.Map;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class StrutsAction extends ActionSupport{private String name;public String getName() {return name;}public void setName(String name) {this.name=name;}public String execute() throws Exception {if(!name.equals("HelloWorld")){Map request=(Map)ActionContext.getContext().get("request");request.put("name",getName());return "success";}else{return "error";}}}


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

public Stringexecute() throws Exception {

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

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

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

  return SUCCESS;

  }else{

  return ERROR;

  }

}








原创粉丝点击