答案:Struts控制器组件负责接受用户请求、更新模型,以及选择合适的视图组件返回给用户。控制器组件有助于将模型层和视图层分离,有了这种分离,就可以在同一个模型的基础上得心应手地开发多种类型的视图。Struts控制器组建主要包括:·ActionServlet组件:充当Struts框架的中央控制器。·RequestProcessor组件:充当每个子应用模块的请求处理器。·Action组件:负责处理一项具体的业务。Struts框架采用控制器组件来预处理所有的客户请求,这种集中控制方式可以满足MVC设计模式的两大需求:·首先,控制器在用户输入数据和模型之间充当媒介 / 翻译者的角色,提供一些通用功能,如安全、登入和其他针对具体用户请求的重要服务,当系统的这些通用功能出现需求变更时,部需要修改整个应用,只需要修改局部的控制器组件即可。·其次,由于所有的请求都经过控制器过滤,因此可以降低视图组件之间,以及视图组件和模型组件之间的相互依赖关系,提高每个组件的相对独立性。由控制器组件来决定把合适的视图组件返回给用用户,这可以减少视图组件之间直接的,错综复杂的连接关系,使应用更加灵活,便于维护。Struts框架采用ActionServlet和RequestProcessor组件进行集中控制,并采用Action组件来处理单项业务。一 控制器组件的控制机制Struts的控制器组件主要完成以下任务:·接受用户请求·根据用户请求,调用合适的模型组件来执行相应的业务逻辑。·获取业务逻辑执行结果。·根据当前状态以及业务逻辑执行结果,选择合适的视图组件返回给用户。1 Action类org.apache.struts.action.ActionServlet类是Struts框架的核心控制器组件,所有的用户请求都先有ActionServlet来处理,然后再由ActionServlet把请求转发给其他组件。Struts框架只允许在一个应用中配置一个ActionServlet类,在应用的生命周期中,仅创建ActionServlet类的一个实例,这个ActionServlet实例可以同时响应多个用户请求。<!--[if !supportLists]-->(a) <!--[endif]-->Struts框架初始化过程<!--[if !supportLists]-->(1) <!--[endif]-->调用initInternal()方法,初始化Struts框架内在的消息资源,如与系统日志相关的同志、警告和错误消息。<!--[if !supportLists]-->(2) <!--[endif]-->调用initOther()方法,从web.xml文件中加载ActionServlet的初始化参数,如config参数。<!--[if !supportLists]-->(3) <!--[endif]-->调用initServlet()方法,从web.xml文件中加载ActionServlet的URL映射信息。此外还会注册web.xml和Struts配置文件所使用的DTD文件,这些DTD文件用来验证web.xml和Struts配置文件的语法。<!--[if !supportLists]-->(4) <!--[endif]-->调用initModuleConfig()方法,加载并解析子应用模块的Struts配置文件;创建ModuleConfig对象,把它存储在ServletContext中。<!--[if !supportLists]-->(5) <!--[endif]-->调用initModuleMessageResources()方法,加载并初始化默认子应用模块的消息资源:创建MessageResources对象,把它存储在ServletContext中。<!--[if !supportLists]-->(6) <!--[endif]-->调用initModuleDataSources()方法,加载并初始化默认子应用模块的数据源。如果在Struts配置文件中没有定义<data-sources>元素,就忽略这一流程。<!--[if !supportLists]-->(7) <!--[endif]-->调用InitModulePlugins()方法,加载并初始化默认子应用模块的所有插件。<!--[if !supportLists]-->(8) <!--[endif]-->当默认子应用模块被成功地初始化后,如果还包括其他子应用模块,将重复流程(4)~(7),分别对其他子应用模块进行初始化。<!--[if !supportLists]-->(b) <!--[endif]-->ActionServlet的process()方法
当ActionServlet实例接受到HTTP请求之后,在doGet()或doPost()方法都会调用process()方法来处理请求。一下是ActionServlet的process()方法的源代码:protected voidprocess (HttpServletRequest request, HttpServletResponse response)throwIOException, ServletException {ModuleUtils.getInstance().selectModule(request,getServletContext());getRequestProcessor(getModuleConfig(request)).process(request,response);}在process()方法中,首先调用org.apache.struts.util.ModuleUtils类的selectModule()方法,这个方法选择负责处理当前请求的子应用模块,然后把与子应用模块相关的ModuleConfig和MessageResources对象存储倒request范围中,这使得框架的其余组件可以方便地从request范围中读取这些对象,从而获取应用配置信息和消息资源。process()方法的第二步操作为获得RequestProcessor类的实例,然后调用RequestProcessor类的process()方法,来完成十几的预处理请求操作。<!--[if !supportLists]-->(c) <!--[endif]-->扩展ActionServlet类在Sturts 1.1 之前的版本中,ActionServlet类本身包含了很多处理请求的代码。从Struts 1.1 开始,多数功能被移到 org.apache.struts.action.RequestProcessor 类中,以便减轻ActionServlet类的控制负担。尽管新版本的Struts框架允许在应用中创建矿展ActionServlet类的子类,但是这在多数情况下没有必要,因为控制器的多数控制功能位于RequestProcessor类中。如果实际应用确实需要创建自己的ActionServlet类,则可以创建一个ActionServlet的子类,然后在web.xml文件中配置这个客户化ActionServlet类。如果覆盖了init()方法,应该确保首先调用super.init(),它保证ActionServlet的默认初始化操作被执行。除了覆盖init()方法外,事实上,还可以根据十几需要覆盖ActionServlet的任何其他方法。
2 RequestProcessor类
对于多应用模块的Struts应用,每个子应用模块都有各自的RequestProcessor实例。在ActionServlet的process()方法中,一旦选择了正确的子应用模块,就会调用子应用模块的RequestProcessor实例的process()方法来处理请求。在ActionServlet调用这个方法时,会把当前的request和response对象传给它。Struts框架只允许应用中存在一个ActionServlet类,但是可以存在多个客户化的RequestProcessor类,每个子应用模块都可以拥有单独的RequestProcessor类。如果想修改RequestProcessor类的一些默认功能,可以覆盖RequestProcessor基类中的相关方法。
<!--[if !supportLists]-->(a) <!--[endif]-->RequestProcessor类的process()方法
RequestProcessor类的process()方法负责实际的预处理请求操作。RequestProcessor类的process()方法一次执行一下流程:(1) 调用processMultipart()方法。如果HTTP请求方式为POST,并且请求的contentType属性以“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(contentType)方法,设置响应结果的文档类型和字符编码。(5) 调用processNoCache()方法,读取ControllerConfig对象的nocache属性,如果nocache属性为true,在响应结果中将加入特定的头参数:Pragma、Cache-Control和Expires,防止页面被存储在客户浏览器的缓存中。(6) 调用processPreprocess()方法。该方法不执行任何操作,直接返回true。子类可以覆盖这个方法,执行客户化的预处理请求操作。(7) 调用processMapping()方法,寻找和用户请求的URI匹配的ActionMapping。如果不存在这样的ActionMapping,则向用户返回恰当的错误消息。(8) 调用processRoles()方法,先判断是否为Action配置了安全角色,如果配置了安全角色,就调用isUserRole()方法判断当前用户是否具备必需的角色;如果不具备,就结束请求处理流程,向用户返回恰当的上一个:TOMCAT完全攻略
下一个:hibernate基础_4
- 更多JSP疑问解答:
- jsp新手求指导,不要笑!
- 如何让一个form提取的值传递给多个jsp?
- DW中,新建的html页面能否有jsp或php代码?
- jsp 如何限制表单,实现只能填写特定的数据。
- jsp 和javabean结合的程序有问题
- 从数据库里取出的数据如何传递到另外的jsp页面中
- 你好,ext嵌入那个jsp页面,是不是还需要加上一些插件啊,不太懂,麻烦你了。
- JSP不能处理所有问题吗?还要来一大堆的TLD,TAG,XML。为JSP 非要 Servlet 不可吗?
- 光标离开时全角转半角在jsp中怎么实现
- jsp 页面 打开 pdf 文件 控制大小 和 工具栏 能发份源码么 谢啦
- jsp页面点保存按钮,运行缓慢,弹出对话框提示
- jsp刷新页面如何不闪屏
- jsp 与html 的交互问题?
- jsp小数显示问题 例如 我在oracle 数据库中查询出来的是 0.01 但是在jsp页面上就显示成 .01 没有前面的0
- jsp中日历控件