struts1:Struts的*控制器

时间:2024-01-18 19:44:50

在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处理用户请求:

struts1:Struts的*控制器//摘自org.apache.struts.action.ActionServlet.
struts1:Struts的*控制器
struts1:Struts的*控制器 public void doGet(HttpServletRequest request, HttpServletResponse response)
struts1:Struts的*控制器    throws IOException, ServletException {
struts1:Struts的*控制器    process(request, response);
struts1:Struts的*控制器    }
struts1:Struts的*控制器    
struts1:Struts的*控制器    public void doPost    (HttpServletRequest request, HttpServletResponse response)
struts1:Struts的*控制器    throws IOException, ServletException {
struts1:Struts的*控制器    process(request, response);
struts1:Struts的*控制器    }
struts1:Struts的*控制器
struts1:Struts的*控制器     protected void process(HttpServletRequest request, HttpServletResponse response)
struts1:Struts的*控制器    throws IOException, ServletException {
struts1:Struts的*控制器    //根据请求选择恰当的应用模块
struts1:Struts的*控制器    ModuleUtils.getInstance().selectModule(request,this.getServletContext());
struts1:Struts的*控制器    ModuleConfig config = getModuleConfig(request);
struts1:Struts的*控制器    //获取模块相关的RequestProcessor实例
struts1:Struts的*控制器    RequestProcessor processor = getProcessorForModule(config);
struts1:Struts的*控制器    if (processor == null)
struts1:Struts的*控制器        processor = getRequestProcessor(config);
struts1:Struts的*控制器        //调用processor实例的process()方法处理请求
struts1:Struts的*控制器    processor.process(request, response);
struts1:Struts的*控制器    }

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

struts1:Struts的*控制器//摘自RequestProcessor
struts1:Struts的*控制器     public void process(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException
struts1:Struts的*控制器     {
struts1:Struts的*控制器         //用一个特殊的包装对象把Muiltipart请求包装起来
struts1:Struts的*控制器         request = processMultipart(request);
struts1:Struts的*控制器         //验证我们用来选择映射的路径组件
struts1:Struts的*控制器         String path = processPath(request, response);
struts1:Struts的*控制器         
struts1:Struts的*控制器         if (path != null) 
struts1:Struts的*控制器         {
struts1:Struts的*控制器            if (log.isDebugEnabled())
struts1:Struts的*控制器            log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'");
struts1:Struts的*控制器           //有请求时, 为当前用户选择一个Locale对象
struts1:Struts的*控制器            processLocale(request, response);
struts1:Struts的*控制器            //有请求时,设置内容类型和no-caching字头
struts1:Struts的*控制器            processContent(request, response);
struts1:Struts的*控制器            processNoCache(request, response);
struts1:Struts的*控制器            if (processPreprocess(request, response))
struts1:Struts的*控制器            {
struts1:Struts的*控制器                processCachedMessages(request, response);
struts1:Struts的*控制器                //验证这个请求的映射
struts1:Struts的*控制器                ActionMapping mapping = processMapping(request, response, path);
struts1:Struts的*控制器                if (mapping != null && processRoles(request, response, mapping)) 
struts1:Struts的*控制器                {
struts1:Struts的*控制器                    //处理和这个请求相关的任何ActionForm bean
struts1:Struts的*控制器                    ActionForm form = processActionForm(request, response, mapping);
struts1:Struts的*控制器                    processPopulate(request, response, form, mapping);
struts1:Struts的*控制器                    if (processValidate(request, response, form, mapping)&& processForward(request, response, mapping)&& processInclude(request, response, mapping)) 
struts1:Struts的*控制器                    {
struts1:Struts的*控制器                        //创建或获取Action实例来处理这项请求
struts1:Struts的*控制器                        Action action = processActionCreate(request, response, mapping);
struts1:Struts的*控制器                        if (action != null)
struts1:Struts的*控制器                        {
struts1:Struts的*控制器                            //调用Action实例本身
struts1:Struts的*控制器                            ActionForward forward = processActionPerform(request, response,action, form, mapping);
struts1:Struts的*控制器                            //处理所返回的ActionForward实例
struts1:Struts的*控制器                            processForwardConfig(request, response, forward);
struts1:Struts的*控制器                        }
struts1:Struts的*控制器                    }
struts1:Struts的*控制器                }
struts1:Struts的*控制器            }
struts1:Struts的*控制器         }
struts1:Struts的*控制器     }

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

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

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