zoukankan      html  css  js  c++  java
  • Struts中央控制器

    Struts的中央控制器

    在Struts框架中,有多个组件分担控制器的工作,它们分别是ActionServlet类,RequestProcessor类和Action类等,其中ActionServlet是Struts框架中的核心控制器。
    Struts应用程序处理用户请求的一般过程
    ActionServlet类作为中心Servlet,负责处理所有到来的用户请求。当ActionServlet接收到一个用户请求时,将执行如下流程:
    1.检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效的错误信息。
    2.如果为ActionMapping配置了Form Bean,则获取相应范围内的ActionForm实例。如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。
    3.根据ActionMapping配置信息决定是否需要验证表单。如果需要验证,就调用ActionForm的validate()方法。
    4.如果ActionForm的validate()方法返回null,或者返回一个不包含任何ActionMessage的ActionErrors对象,就表明表单验证成功,继续执行下一步。否则返回input属性指定的页面,并向用户显示ActionErrors集合中的错误信息。
    5.ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给哪个Action,如果相应的Action实例不存在,则先创建这个实例,然后调用Action的execute方法。
    6.Action的execute方法返回 一个ActionForward对象,ActionServlet将请求转发到这个ActionForward对象指定的组件,通常是一个JSP组件或其他Action。
    7.如果ActionForward对象指向一个JSP组件,则将该JSP生成的动态页面返回给用户;如果ActionForward对象指向的仍然是一个Action,则从第1步重新开始执行!
    从上述过程可知ActionServlet类是Struts框架的内置核心控制器组件,它继承了javax.servlet.http.HttpServlet类。Struts的启动通常从加载ActionServlet开始。Web容器会在首次启动或Struts应用的第一个请求到达时加载ActionServlet。
    ActionServlet第一次被加载后,其init()方法被调用。在init()方法中,Struts框架执行所有必要的初始化工作。
    然后,Web容器将调用ActionServlet的doPost()或doGet()方法来处理用户请求,而它们实际上都是调用process()方法具体处理请求的,如下列代码:
    ActionServlet处理用户请求:

    //摘自org.apache.struts.action.ActionServlet.

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
        process(request, response);
        }

    public void doPost    (HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
        process(request, response);
        }

    protected void process(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    //根据请求选择恰当的应用模块
        ModuleUtils.getInstance().selectModule(request,this.getServletContext());
        ModuleConfig config = getModuleConfig(request);
    //获取模块相关的RequestProcessor实例
        RequestProcessor processor = getProcessorForModule(config);
    if (processor == null)
            processor = getRequestProcessor(config);
    //调用processor实例的process()方法处理请求
        processor.process(request, response);
        }

    在上面我们看到ActionServlet的process()方法中实际处理用户请求的是RequestProcessor类的process()方法。Struts框架只允许应用程序中存在一个ActionServlet类,但每个应用程序模块都有各自的RequestProcessor类实例。在ActionServlet的process()方法中,一旦选择了正确的应用程序模块,就会调用相应模块RequestProcessor实例的process()方法来处理请求。RequestProcessor类的process方法如下:

    //摘自RequestProcessor
    public void process(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException
    {
    //用一个特殊的包装对象把Muiltipart请求包装起来
             request = processMultipart(request);
    //验证我们用来选择映射的路径组件
             String path = processPath(request, response);

    if (path != null)
     {
    if (log.isDebugEnabled())
                log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'");
    //有请求时, 为当前用户选择一个Locale对象
                processLocale(request, response);
    //有请求时,设置内容类型和no-caching字头
                processContent(request, response);
                processNoCache(request, response);
    if (processPreprocess(request, response))
    {
                    processCachedMessages(request, response);
    //验证这个请求的映射
                    ActionMapping mapping = processMapping(request, response, path);
    if (mapping != null && processRoles(request, response, mapping))
    {
    //处理和这个请求相关的任何ActionForm bean
                        ActionForm form = processActionForm(request, response, mapping);
                        processPopulate(request, response, form, mapping);
    if (processValidate(request, response, form, mapping)&& processForward(request, response, mapping)&& processInclude(request, response, mapping))
    {
    //创建或获取Action实例来处理这项请求
                            Action action = processActionCreate(request, response, mapping);
    if (action != null)
    {
    //调用Action实例本身
                                ActionForward forward = processActionPerform(request, response,action, form, mapping);
    //处理所返回的ActionForward实例
                                processForwardConfig(request, response, forward);
                            }
                        }
                    }
                }
             }
         }

    ActionServlet在web.xml中的配置:
      像所有Servlet一样,ActionServlet也需要在web.xml中进行配置。其具体配置方法如下:

    <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
    <param-name>debug</param-name>
    <param-value>3</param-value>
    </init-param>
    <init-param>
    <param-name>detail</param-name>
    <param-value>3</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    需要特别说明的是,Struts的配置文件struts-config.xml作为ActionServlet的一个初始化参数值在web.xml文件中声明。另外,ActionServlet的URL形式是*.do,这样当在浏览器地址输入任何后缀为*.do的URL时,系统都会映射到ActionServlet。

    原文出处http://www.cnblogs.com/eflylab/archive/2007/01/08/614445.html

  • 相关阅读:
    33.数组声明方式(var构造函数) 、检测数组类型、数组的属性(封装好的就一个length)、数组的方法
    31.this指向(写出调用链,找最近对象) this的默认绑定 隐式绑定 显示绑定(call(绑定对象) apply(绑定对象) 当括号内没放绑定对象的时候恢复默认绑定) bind
    31.
    30.函数作用域链 (GO AO 也叫词法作用域链)、 调用栈、调用栈涉及this绑定
    29.包装类(构造函数) 包装类作用及调用栈
    916. Word Subsets
    246. Strobogrammatic Number
    445. Add Two Numbers II
    2. Add Two Numbers
    341. Flatten Nested List Iterator
  • 原文地址:https://www.cnblogs.com/andyboy/p/3036955.html
Copyright © 2011-2022 走看看