Struts初始化之RequestProcessor

本文详细解析了Struts框架中的RequestProcessor类的作用及其执行流程,包括如何处理HTTP请求、选择映射、验证表单等关键步骤,并展示了如何通过扩展RequestProcessor类来实现用户的Locale设置更改。
对于RequestProcessor这个类,有的人可能很陌生,毕竟它不象ActionSerlvet那样,在我们的面前频繁的出现。但是,RequestProcessor用的要远比ActionServlet多,那么RequestProcessor到底是干什么的呢?当ActionServlet接收到客户请求后,会进行一连串的初始化操作,然后,就会将客户请求转交给合适的处理器进行处理,这个合适的处理器就是org.apache.struts.action.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类的扩展。


上面这些分析,也是我在网上搜集的资料并加以整理总结出来的,在实际的应用开发中,如果我们想对Struts在初始化的时候进行一些扩展,我们可以重新写ActionServlet的子类,或RequestProcessor的子类,但是不建议去写ActionServlet的子类,在RequestProcessor中为我们提供了processPreprocess()这个钩子方法,这样,我们可以去重写这个方法,来进行扩展。虽然RequestProcessor在表面上不是很常用到,但是他给人的感觉却恰恰相反,这个类用来处理我们每一次的请求,所以,更好的了解RequestProcessor类对我们来说很重要。
127.0.0.1:7001/dcms_index.view? 华夏银行 在线客服 户管理 bjq 审会会议通知信任务池 本会会议纪要企业资产证券化管理 Error 500--Internal Server Error 受信额度停用申请放款管理 贷后管理 javax. servlet.isp.IsnException. Exception creating bean of class com.ebworx. hxb. mcif. training.struts. controller. TrainingLscCustomerActionForm:(1) 同一务人管理 跨条线副资管理 at org. apache.struts.taglib.html. FormIag. doStartTag (FornTag.java:520) at org.apache.struts. taglib.html.FormIag.initFormBean (FormTag.java:563) at org. apache.strutsel.taglib.html.ELFormTag.doStartTag(ELFormTag.java:324) 档案管理 at jsp_servlet._dcms._base._menu_interface._jsp_tag2(_menu_interface. java:204) 回收与清侃 at weblogic.servlet. jsp.JspBase.service(JspBase.java:34) at jsp_servlet._dcms._base.__menu_interface._jspService(_menu_interface.java 130) 调整业务信息 at weblogic.servlet.internal. StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) 调整流星信息 at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) 系统参数维护 at weblogic.servlet.internal.TailFilter.doFilter (TailFilter.java:26) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301) 报表查询 at weblogic.servlet.internal.FilterChainInpl.doFilter (FilterChainImpl.java:56) 信息与公告 at com.haian.hxb.itsm.filter.XssFilter.doFilter (XssFilter.java:30) at weblogic.servlet.internal.FilterChainImpl. doFilter (FilterChainImpl.java:56) 担保变更 at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:527) 调整用户电息 at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:253) at common.web.struts.service.RequestProcessor.doForvard (RequestProcessor.java:1067) at common.web.struts. service.RequestProcessor.internalModuleRelativeForvard(RequestProcessor.java:1010) at common.web.struts. service.RequestProcessor.processForvard(RequestProcessor.java:580) at common.web.struts. service.RequestProcessor. process(RequestProcessor.java:257) at org.apache.struts.action.ActionServlet,process(ActionServlet.java:1482) at org.apache. struts.action.ActionServlet.doGet (ActionServlet.Java:507) iosyearulet rernceHetnSarx]et:7071 DevTools is now available in Chinesel Always match Chrome's language Switch DevTools to Chinese Dontsnow agan Elements Console Sources Network Performance Memory Application Security Lighthouse Recorder Performance insights A Preserve log□Disable cache No throttling Fiter 1nvert Hide data URLs☑Hide extension URLc All Fotch/XHR oos Css s Font img Meda Manifest Ws walm other o Blcked reauest 20000ms 40000
最新发布
03-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值