1、Struts扩展控制器及导航设置,,教学目标,Struts控制器的组成 理解struts框架的初始化流程 理解struts框架的响应客户请求的流程 理解struts框架响应客户请求的流程 Struts中定制前端控制器 Struts中配置多模块开发,Struts控制器的组成,在Struts各种组件中最重要的组件就是控制器组件 Struts控制器组件的组成Struts控制器主要由ActionServlet组成,另外包含RequestProcessor Action 及 ActionForward三个辅助类,Struts多应用模块,多应用模块是指同一个应用包含多个子应用,每个子应用可以处理相关的一组
2、功能,例如:对于网上购物,可以由一个子应用来处理商品和商品目录信息再由另一个子应用来处理购物车和订单信息 把应用划分为多个模块,可以简化应用的并行开发过程,缩短开发周期 在Struts中,所有的子应用都共享同一个ServletAction但是每一个子应用都有单独的配置文件和RequestProcesser实例,Struts多应用模块,Struts 框架的初始化流程,Servlet容器会在ActionServlet被加载后立即执行它的init()方法,以下是ActionServlet的init的执行过程分析: 调用initInternal()方法,初始化所有在Struts框架中用到的消息资源,例
3、如:日志,警告,错误信息等 调用initOther()方法,从web.xml中加载ActionServlet的初始化参数,例如:config等 调用initServlet()方法,从web.xml中加载ActionServlet的URL映射信息,Struts 框架的初始化流程,调用initModuleConfig()方法,加载并解析默认子应用模块的Struts配置文件,并创建ModuleConfig对象,并且将它存储在ServletContext中 调用initModuleMessageResource()方法,加载并初始化默认子应用模块的消息资源,并且建立MessageResources对象
4、,并将它保存在ServletContext中 调用initModuleDataSource()方法,加载并实始化默认的子应用模块数据源,如果没有在struts的配置文件中配置元素,这一步将被忽略 调用initModulePlugins()方法,加载并初始化默认子应用模块的所有插件 当默认的子应用模块初始化成功后,如果还有其它的子应用模块,ActionServlet将重复4到7的步骤,分别对其它子模块进行初始化,Struts 框架的初始化流程,Struts 框架响应客户请求的流程,Struts 框架响应客户请求的流程,当ActionServlet实例接收到HTTP请求后,在doGet()和doP
5、ost()方法中都会调用process()方法来处理请求ModuleUtils.getInstance().selectModule(request, getServletContext();/选择请求相关的子应用模块ModuleConfig config = getModuleConfig(request);/获取请求相关的配置文件RequestProcessor processor = getProcessorForModule(config);/获取请求相关的处理器if (processor = null) processor = getRequestProcessor(config);
6、processor.process(request, response);,RequestProcesser的process()方法,首先调用processMultipart()方法如果Http请求的为Post方法,并且请求的Content-type的类型为mutipart/form-data,标准的HttpServletRequest将被重新封装以处理多数据体的Http请求,如果没有设定Content-type则直接返回HttpServletRequest对象 调用processPath()方法,获取请求的URI路径,该信息用于选择合适的Action组件 调用processLocale()方
7、法,当ControllerConfig中的locale属性为true时,将读取用户请求中包含的locale信息,然后把locale信息保存在session范围内 调用processContent()方法,读取ControllerConfig中的contentType属性,然后调用response.setContentType(contentType)的方法设置响应的文档类型及字符编码,RequestProcesser的process()方法,调用processNoCache()方法,通过读取ControllerConfig对象的nocache属性来设置是否在客户端的浏览器中缓存页面如果参数为t
8、rue,那么将在响应的头信息中加入特定的头信息:Pragma, Cache-Control和Expries 调用processPreprocess()方法该方法用于自定义的RequestProcesser重载,执行客户化的预处理请求操作返回true表示预处理成功 调用processMapping()方法,在此寻找与用户请求相匹配的ActionMapping,如果不存在则返回出错信息 调用processRoles()方法,该方法先判断对应请求的Action是否配置了安全角色,如果配置了安全角色就调用isUserInRole()方法来确定用户是否具备该角色,如果不具备将返回错误信息,Request
9、Processer的process()方法,调用processActionForm()方法,该方法先判断是否为ActionMapping配置了ActionForm,如果配置了ActionForm,就先从ActionForm的存在范围内查找该ActionForm的实例,如果不存在就创建一个新的实例,接下来将它保存在合适的范围中,保存时的属性名称为ActionMapping中配置的name属性值 调用processPopulate()方法该方法检查ActionMapping是否配置了ActionForm,如果找到就调用ActionForm的reset()方法,再把请求中的数据装载到ActionFo
10、rm中 调用processValidate()方法,如果ActionMapping配置了ActionForm,并且属性validate为true,此时将调用ActionForm的validate()方法如果validate()方法返回的ActionErrors对象中包含ActionMessage对象,说明表单验证失败,此时将ActionErrors对象存储在request的范围中,再把请求发送给ActionMapping的input属性指定的Web组件如果ActionForm的validate()返回空则表示验证成功,就继续执行下一步处理流程,RequestProcesser的process(
11、)方法,接下来调用processForward()方法,该方法判断是否在ActionMapping中配置了forward属性,如果配置了这个属性就调用RequestDispatcher的forward()方法,执行转向,请求处理流程就结束了,否则进行下一步操作 调用processInclude()方法,该方法判断是否在ActionMapping中配置了include属性,如果配置了该属性就调用RequestDispatcher的include()方法,请求处理流程就结束了,否则进行下一步操作 调用processActionCreate(),该方法用于获取请求对应的Action,它先判断是否在A
12、ction缓存中存在这个Action的实例,如果不存在,就建立一个并将它保存在缓存中 调用processActionPerferm()方法,该方法调用Action的execute方法,execute方法位于try catch中,以便捕获异常 调用processActionForward()方法,把Action执行之后返回的ActionForward对象作为参数传给它,该方法根据ActionForward指定的转发路径来执行转发或重定向操作,Action类的execute方法,execute方法的参数ActionMapping :包含了该Action的配置信息,对应配置文件的action节点Ac
13、tionForm :包含了用户的表单数据,当Struts框架调用execute()方法时,ActionForm中的数据已经通过了表单的验证HttpServletRequest:当前的Http请求对象HttpServletResponse :当前的Http响应对象 该方法返回一ActionForward对象它包含了请求转发的路径信息,定制Struts控制器组件,定制Struts的ActionServlet,实际上只需要定制org.apache.struts.action.RequestProcessor 类即可,该类真正包含了Struts在处理Servlet请求时所遵循的控制逻辑,该类的的process方法用来委托处理客户请求,其中的定义一个预定义方法processPreprocess专门用于实现定制的控制逻辑 在完成自定义的类后需要在对应模块的配置文件中加入元素,它的属性type指定自定义的控制类路径 例: ,Struts导航设置,