您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Struts 2详细工作流程 (2)
Struts2详细工作流程Struts2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。3.1.1核心控制器FilterDispatcher核心控制器FilterDispatcher是Struts2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。Struts2的工作流程相对于Struts1要简单,与WebWork框架基本相同,所以说Struts2是WebWork的升级版本。Struts2框架按照模块来划分,可以分为ServletFilters、Struts核心模块、拦截器和用户实现部分。Struts2框架结构图如图3.1所示。图3.1Struts2框架结构图一个请求在Struts2框架中的处理大概分为以下几个步骤。客户端提交一个(HttpServletRequest)请求,如上文在浏览器中输入就是提交一个(HttpServletRequest)请求。请求被提交到一系列(主要是3层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、FilterDispatcher)。注意:这里是有顺序的,先ActionContextCleanUp,再其他过滤器(OthterFilters、SiteMesh等),最后到FilterDispatcher。FilterDispatcher是控制器的核心,就是MVC的Struts2实现中控制层(Controller)的核心。FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServletRequest)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。ActionProxy通过ConfigurationManager(struts.xml)询问框架的配置文件,找到需要调用的Action类。例如,用户注册示例将找到UserReg类。ActionProxy创建一个ActionInvocation实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。Struts2的核心控制器是FilterDispatcher,有3个重要的方法:destroy()、doFilter()和Init(),可以在Struts2的下载文件夹中找到源代码,如代码3.1所示。代码3.1核心控制器FilterDispatcherpublicclassFilterDispatcherimplementsStrutsStatics,Filter{/***定义一个Log实例*/privatestaticfinalLogLOG=LogFactory.getLog(FilterDispatcher.class);….../***存放属性文件中的.STRUTS_I18N_ENCODING值*/privatestaticStringencoding;/***定义ActionMapper实例*/privatestaticActionMapperactionMapper;/***定义FilterConfig实例*/privateFilterConfigfilterConfig;protectedDispatcherdispatcher;/***创建一个默认的dispatcher,初始化filter*设置默认的packages**/publicvoidinit(FilterConfigfilterConfig)throwsServletException{this.filterConfig=filterConfig;dispatcher=createDispatcher(filterConfig);dispatcher.init();Stringparam=filterConfig.getInitParameter(packages);Stringpackages=org.apache.struts2.statictemplateorg.apache.struts2.interceptor.debugging;if(param!=null){packages=param++packages;}this.pathPrefixes=parse(packages);}//销毁filter方法publicvoiddestroy(){if(dispatcher==null){LOG.warn(somethingisseriouslywrong,Dispatcherisnotinitialized(null));}else{dispatcher.cleanup();}}/***处理一个Action或者资源请求*p/*filter尝试将请求同actionmapping相匹配*如果找到,将执行dispatcher的serviceAction方法*如果Action处理失败,doFilter将建立一个异常*p/*如果请求静态资源*资源将被直接复制给response*p/*如果找不到匹配Action或者静态资源,则直接跳出publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException{HttpServletRequestrequest=(HttpServletRequest)req;HttpServletResponseresponse=(HttpServletResponse)res;ServletContextservletContext=getServletContext();StringtimerKey=FilterDispatcher_doFilter:;try{UtilTimerStack.push(timerKey);request=prepareDispatcherAndWrapRequest(request,response);ActionMappingmapping;try{mapping=actionMapper.getMapping(request,dispatcher.getConfigurationManager());}catch(Exceptionex){LOG.error(errorgettingActionMapping,ex);dispatcher.sendError(request,response,servletContext,HttpServletResponse.SC_INTERNAL_SERVER_ERROR,ex);return;}if(mapping==null){StringresourcePath=RequestUtils.getServletPath(request);if(.equals(resourcePath)&&null!=request.getPathInfo()){resourcePath=request.getPathInfo();}if(serveStatic&&resourcePath.startsWith(/struts)){Stringname=resourcePath.substring(/struts.length());findStaticResource(name,request,response);}else{//为一个普通的request,则通过chain.doFilter(request,response);}return;}/***这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,*如果ActionMapper决定需要调用某个Action,*FilterDispatcher则把请求的处理交给ActionProxydispatcher.serviceAction(request,response,servletContext,mapping);}finally{try{ActionContextCleanUp.cleanUp(req);}finally{UtilTimerStack.pop(timerKey);}}}……}在doFilter()方法中,将调用dispatcher.serviceAction,该方法如果找到相应的Action,将把用户请求交给ActionProxy。serviceAction()代码在Dispatcher.java中,如代码3.2所示。代码3.2Dispatcher类publicclassDispatcher{.../***为mapping加载类,并调用相应的方法或者直接返回result*p/*根据用户请求的参数,建立Action上下文*根据指定的Action’名称和包空间名称,加载一个Action代理ttActionProxy/tt*然后Action的相应方法将被执行,*/publicvoidserviceAction(HttpServletRequestrequest,HttpServletResponseresponse,ServletContextcontext,ActionMappingmapping)throwsServletException{MapString,ObjectextraContext=createContextMap(request,response,mapping,context);//如果存在一个值栈,则建立一个新的并复制以备Action使用ValueStackstack=(ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);if(stack!=null){extraContext.put(ActionContext.VALUE_STACK,ValueStackFactory.getFactory().createValueStack(stack));}StringtimerKey=HandlingrequestfromDispatcher;try{UtilTimerStack.push(timerKey);Stringnamespace=mapping.getNamespace();Stringname=mapping.getName();Stringmethod=mapping.getMethod();Configurationconfig=configurationManager.getConfiguration();//FilterDispatcher把请求的处理交给ActionProxyActionProxyproxy=config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace,name,extraContext,true,false);proxy.setMethod(method);request.setAttribute(ServletActionContext.
本文标题:Struts 2详细工作流程 (2)
链接地址:https://www.777doc.com/doc-3364144 .html