Struts控制器组件---RequestProcessor类

来源:互联网 发布:对韩国人的印象 知乎 编辑:程序博客网 时间:2024/05/01 18:51

RequestProcessor类

Struts框架只允许应用中存在一个ActionServlet类,但是可以存在多个客户化的RequestProcessor类,每个子应用模块都可以拥有单独的RequestProcessor类,如果像修改RequestProcessor类的一些默认功能,可以覆盖RequestProcessor基类中的相关方法。

下面我们来介绍其中的process()方法:

pubic void process(HttpServletRequest request,HttpServletResponse reponse) throws IOException,ServletException {

//Wrap multipart requests with a special wrapper

      request=processMultipart(request);

//Identify the path component we will use to select a mapping

      String path=processPath(request,response);

      if(path==null){

         return;

        }

      if(log.isDebugEnabled()){

         log.debug(“processing a ”+request.getMethod()+”for path”+path+””)

        }

//select a locale for the current user if requested

processLocale(request,response);

 

//set the content type and no-caching headers if requested

processContent(request,response);

processNoCache(request,response);

 

//General purpose preprocessing hook

if(!processPreprocess(request,response)) {

     return;

}

 

//identify the mapping for this request

ActionMapping mapping=processMapping(request,response,path);

If(mapping==null) {

      return;

}

 

//check for any role required to perform this action

if(!processRoles(request,response,mapping)) {

      return;

}

 

//process any actionForm bean related to this request

ActionForm form=processActionForm(request,response,mapping);

processPopulate(request,response,form,mapping);

if(!prcessValidate(request,response,form,mapping)) {

     return;

}

 

//process a forward or include specified by this mapping

if(!processForward(request,response,mapping)) {

      return;

}

if(!processInclude(request,response,mapping)) {

      return;

}

 

//create or acquire the Action instance to process this request

Action action=processActionCreate(request,response,mapping);

If(action==null) {

    return;

}

 

//call the action instance itself

ActionForward forward=processActionPerform(request,response,form,mapping);

 

//process the returned ActionForm instance

processForwardConfig(request,response,forward);

}

其执行流程如下:

(1)                调用processMultipart()方法,如果HTTP请求方式为POST,并且请求的coutentType属性以”Multipart/form-data”开头,标准的HttpServletRequest对象将被重新包装,以方便处理“Multipart”类型的HTTP请求,如果请求方式为GET,或者contentType属性不是“multipart”,就直接返回原始的HttpServletRequest对象。

(2)                调用processPath(),获得请求URI路径,这一信息可用于选择合适的Struts Action组件。

(3)                调用processLocale()方法,当ControllerConfig对象的locale属性为true,将读取用户请求中包含的Locale信息,然后把Locale实例保存在session范围内。

(4)                 调用processContent(),读取ControllerConfig对象的contentType属性,然后调用response.setContentType(content Type)方法,设置响应结果的文档类型和字符编码。processContent()方法的代码如下:

protected void processContent(HttpServletRequest request,HttpServletResponse){

        String contentType=moduleConfig.getControllerConfig().getContentType();

If(contentType!=null) {

        Response.setContentType(contentType);

     }

}

(5)                调用processNoCache(),读取ControllerConfig对象的nocache属性,如果nocache属性为true,在响应结果中将加入特定的头参数:Pragma,Cache-Control和Expires,防止页面被存储在客户浏览器的缓存中,processNoCache()方法的代码如下:

protected void processNoCache(HttpServletRequest request,HttpServletResponse response){

     if(moduleConfig.getControllerConfig().getNoCache()) {

          response.setHeader(“Pragma”,”NoCache”);

          response.setHeader(“Cache-Control”,”no-cache”);

          response.setHeader(“Expires”,1);

        }

}

(6)                调用processPreprocess(),该方法不执行任何操作,直接返回true,子类可以覆盖这个方法,执行客户化的预处理请求操作。

(7)                调用processMapping(),寻找和用户请求的URI匹配的ActionMapping,如果不存在这样的ActionMapping,则向用户返回恰当的错误信息。

(8)                调用processRoles(),现判断是否为Action配置了安全角色,如果配置了安全角色,叫调用isUserInRole()方法判断当前用户是否具备必须的角色。如果不具备,就结束请求处理流程,向用户返回恰当的错误信息。

(9)                调用processActionForm(),现判断是否为ActionMapping配置了ActionForm,如果配置了ActionForm(),就先从ActionForm的存在范围内寻找该ActionForm的实例,如果不存在,就创建一个实例,接下来把它保存在合适的范围内,保存时使用的属性key为ActionForm的name属性。

(10)            调用processPopulate()方法,如果为ActionMapping配置了ActionForm,就先调用ActonForm的reset()方法,再把请求中的表单数据组装到ActionFrom中。

(11)            调用processValidate(),如果为ActionMapping 配置了ActionForm,并且ActionMapping 的validate属性为true,就调用ActionForm的validate()方法,如果validate()方法返回的ActionErrors对象中包含ActionMessage对象,说明表单验证失败,就把ActionErrors对象存储在request范围内,再把请求转发到ActionMapping的input属性指定的WEB组件,如果ActionForm的valildate()方法执行表单验证成功,就继续执行下一个请求处理流程。

(12)            调用processForward(),判断是否在ActionMapping中配置了forward属性,如果配置了这个属性,就调用RequestDispatcher的forward()方法,请求处理流程结束,否则进行下一步。

(13)            调用processInclude(),判断是否在ActionMapping中配置了include属性,如果配置了这个属性,就调用RequestDispatcher的include()方法,请求处理流程结束,否则进行下一步。

(14)            调用processActionCreate()方法,现判断是否在Action缓存中存在这个Action实例,如果不存在,就创建一个实例,把它保存在Action缓存中。

(15)            调用processActionPerform()方法,该方法再调用Action实例的execute()方法,execute()方法位于try/catch代码中,以便捕获异常。代码如下:

protected ActionForward processActionPerform(HttpServletRequest request,HttpServletResponse response,Action action, ActionMapping mapping)throws IOException,ServletException{

   try{

         return(action.execute(mapping,form,request,response));

       }catch(Exception e){

         return(processException(request,response,e,form,mapping));

       }

}

(16)            调用processActionForward()方法,把Action 的execute()方法返回的ActionForward对象作为参数来传给它。processActionForward()根据ActionFroward对象包含的请求转发信息来执行请求转发或重定向。

注意:在struts中,ControllerConfig类与配置文件中的<controller>元素对应,ActionMapping类和<action>元素对应,ActionForward类和<forward>元素对应

扩展RequestProcessor类

下面我们来实现用户在同一个会话的任何时候都可以改变它的Locale设置,在RequestProcessor类中定义的processLocale()方法的默认行为是: 仅仅当session范围呢不存在Locale实例的时候,才会把Locale实例保存在session内,这通发生在处理同一个对话的第一个请求时。

那么我们怎样实现在同一个会话的任何时候都可以改变它的Locale设置呢?我们扩展RequestProcessor类,检查每次用户发出的HTTP请求中包含的Locale信息,每当Locale发生变化时,就会把新的Locale实例保存在session范围内。

代码如下:

package sample;
import javax.servlet.http*;

import java.util.Locale;

import org.apache.struts.action.Action;

import org.apache.struts.action.RequestProcessor;

import org.apache.struts.action.Globals;

 

public class ExtendedRequestProcessor extends RequestProcessor{

      protected void processLocale(HttpServletRequest request,HttpServletResponse response){

        if(!moduleConfig.getControllerConfig().getLocale()){

           return

               }//end if

//get the locale that stored in the user’s session if any

        HttpSession session=request.getSession();

        Locale sessionLocale=(Locale)session.getAttribute(Globals.LOCALE_KEY);

        }

//get the user’s preferred Locale form the request

       Locale requestLocale=request.getLocale();

 

//if was never a locale in the session or it has changed ,set it

if(sessionLocale==null||(sessionLocale!=requestLocale)){

           if(log.isDebugEnabled()) {

                 log.debug(“Setting user locale”+requestLocale+””);

                   }//end if (log.isDebug)

//set new locale into the user’s session

   session.setAttribute(Globals.LOCALE_KEY,requestLocale);

           }//end if(sessionLocale==null……)

  }//end protected void processLocale(…)

}//end of ExtendedRequestProcessor class

然后在struts配置文件中,<controller>元素的processClass属性用来配置上面扩展好的类,我们就可以在struts中使用这个类

<controller

 contentType=”text/html;charset=GB2312”

 locale=”true”

 nocache=”true”

 processClass=”sample.ExtendedRequestProcessor”/>

到这里,我么就完成了对RequestProcessor类的扩展。

原创粉丝点击