`

扩展Struts(2)

阅读更多

Request是如何被处理的

  ActionServlet是Struts框架中唯一的Servlet,它负责处理所有request。无论何时接收到一个request,它都会先尝试为当前的request寻找一个sub-application。一旦一个sub-application被找到,ActionServlet就会为那个sub-application创建一个RequestProcessor对象,调用这个对象的process()方法并把HttpServletRequest和HttpServletResponse对象传入。

  RequestProcessor.process()就是大部分request被处理的地方。process()方法使用了Template Method模式实现,其中有很多独立的方法来执行请求处理的每一步骤,这些方法将会在process方法中依次被调用。比如,将会有一个独立的方法用来寻找当前request对应的ActionForm类,一个方法来检查当前用户是否有执行action mapping所必须的权限。这些给与我们极大的灵活性。在发布的Struts包中有一个RequestProcessor类提供了请求处理每一步骤的默认实现。这就意味着你可以仅仅重写你感兴趣的方法,其它的使用默认的实现。举例来说,默认地Struts调用request.isUserInRole()来检查用户是否有权限执行当前的ActionMapping;这时如果你想通过查询数据库来实现,你所要做的就是重写processRoles()方法,通过查询出的用户是否拥有必须的权限来返回true或false。

  首先我们将会看到缺省情况下,process()方法是如何实现的,然后我将会详细解释默认的RequestProcessor类中的每一个方法,这样你就可以决定哪一部分是你想要改变的。

public void process(HttpServletRequest request,HttpServletResponse response)
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 (!processValidate(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,action, form, mapping);
// Process the returned ActionForward instance
processForwardConfig(request, response, forward);
}

 
  1、processMutipart():在这个方法中,Struts将会读取request来检查request的contentType是否是multipart/form-data。如果是的话,将会解析request并且将之包装到HttpServletRequest中。当你创建了一个HTML FORM用来提交数据,那么request的contentType默认就是application/x-www-form-urlencoded。但是如果你的form使用了file类型的input控件允许用户上传文件的话,你就必须将contentType改为multipart/form-data。如果是这样的情况,你就不能再通过getParameter()来获取用户提交的数据;你必须将request作为一个InputStream来读取,并且自己解析它来获得参数值。

  2、processPath():在这个方法中,Struts将会读取request的URI,来确定路径元素,这个元素是用来获取ActionMappint元素。

  3、processLocale():在这个方法中,Struts将会为当前request取得Locale,如果配置过的话,还可以将这个对象作为HttpSession中org.apache.struts.action.LOCALE属性的值而保存。作为这个方法的副作用,HttpSession将会被创建,如果你不想创建的话,你可以在ControllerConfig中将locale属性设为false,在struts-config.xml中象如下这样:

<controller>
 <set-property property="locale" value="false"/>
</controller>
  4、processContent():通过调用response.setContentType()来为response设置contentType。这个方法首先会尝试从struts-config.xml配置中得到contentType。缺省情况下使用text/html。如果想覆盖它,可以象如下这样:

<controller>
<set-property property="contentType" value="text/plain"/>
</controller>

 
  5、processNoCache():如果配置是no-cache,Struts将会为每个response设置下面三个headers:

requested in struts config.xml
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 1);
  如果你想设置no-cache header,在struts-config.xml中加入下面信息:

<controller>
<set-property property="noCache" value="true"/>
</controller>
  6、processPreprocess():这个方法为预处理提供一个hook,可以在子类中覆盖它。它的缺省实现没有作任何事情,总是返回true。返回false的话将会终止当前请求的处理。

  7、processMapping():这个方法将会用路径信息得到一个ActionMapping对象。也就是struts-config.xml文件中的<action>元素:

<action path="/newcontact" type="com.sample.NewContactAction" name="newContactForm" scope="request">
<forward name="sucess" path="/sucessPage.do"/>
<forward name="failure" path="/failurePage.do"/>
</action>

 
  ActionMapping元素包含了Action类的名称和处理请求使用的ActionForm等等信息。它还包含当前ActionMapping配置的ActionForwards信息。

  8、processRoles():Struts web应用提供了一个授权方案。也就是说,一旦一个用户登入了容器,struts的processRoles()方法将会通过调用request.isUserInRole(),来检查他是否有必须的角色来运行一个给定的ActionMapping。

<action path="/addUser" roles="administrator"/>
  假设你有一个AddUserAction并且你只想让administrator能够增加新的user。你所要做的就是给你的AddUserAction元素增加一个role属性,这个属性的值为administrator。这样,在运行AddUserAction之前,这个方法会确保用户拥有administraotr的角色。

  9、processActionForm():每一个ActionMapping都一个相应的ActionForm类。当Struts处理一个ActionMapping的时候,它将会从<action>元素的name属性中找出对应的ActionForm类的名称。

<form-bean name="newContactForm" type="org.apache.struts.action.DynaActionForm">
 <form-property name="firstName" type="java.lang.String"/>
 <form-property name="lastName" type="java.lang.String"/>
</form-bean>
  在我们的例子中,它会先在request scope中检查是否有一个org.apache.struts.action.DynaActionForm类的对象存在。如果有它将会使用这个对象,如果没有它将会创建一个新的对象并把它设置在request scope。

  10、processPopulate():在这个方法中,Struts将会用相匹配的request参数装配ActionForm的实例变量。

  11、processValidate():Struts将会调用你的ActionForm类的validate方法。如果你从validate()返回ActionErrors,它将会将user重定向到<action>元素的input属性指定的页面。

  12、processForward()和processInclude():在这些方法中,Struts将会检查<action>元素的forward或include属性,如果找到了,将会把forward或include请求放置到配置的页面中。

<action forward="/Login.jsp" path="/loginInput"/>
<action include="/Login.jsp" path="/loginInput"/>
  你可以从这些方法的名字上猜测它们的不同:processForward()最终调用RequestDispatcher.forward(),而processInclude()调用RequestDispatcher.include()。如果你同时配置了forward和include属性,它将会总是调用forward,因为forward先被处理。

  13、processActionCreate():这个方法从<action>元素的type属性中获取获得Action类的名字并且创建返回它的实例。在我们的例子中,它将会创建一个com.sample.NewContactAction类的实例。

  14、processActionPerform():这个方法调用你的Action类的excute()方法,你的业务逻辑也就是在excute方法中。

  15、processForwardConfig():你的Action类的excute()方法将会返回一个ActionForward对象,这个对象将指出哪个页面是显示给用户的页面。因此,Struts将会为那个页面创建一个RequestDispatcher,并且调用RequestDispatcher.forward()。

  上面的列表说明了默认的RequestProcessor实现在处理请求时每一步作的工作,以及执行的顺序。正如你所看到的,RequestProcessor是非常灵活的,允许你通过设置<controller>元素的属性来配置它。举例来说,如果你的应用准备生成XML内容来代替HTML,你就可以通过设置controller元素的属性来通知Struts这些情况。

分享到:
评论

相关推荐

    在struts2的freemarker模板中扩展struts标签

    众所周知,struts2宣称freemarker模板中不再支持自定义标签,但如果工程UI仅用freemarker模板可以通过扩展struts标签简单实现,不是采用官方不推荐的配置JspSupportServlet实现的!内付详细说明及范例,此方法仅为团队...

    使用freemarker扩展struts标签

    本话题将深入探讨如何使用FreeMarker扩展Struts2的标签库,以增强视图层的表现力和灵活性。 首先,FreeMarker是一个基于模板的语言,它允许开发者用简单的语法来处理数据模型并生成HTML或其他文本。在Struts2中,...

    Struts2接口文档

    这些插件通过扩展Struts2的能力,使得开发者能够构建更复杂、更灵活的应用。 总的来说,Struts2接口文档是学习和使用Struts2框架不可或缺的工具,它能帮助开发者高效地理解和使用框架提供的各种组件和接口,提升...

    struts2所用到的jar包

    这些插件通常包含自己的jar包,以扩展Struts2的功能,如 strut2-convention-plugin 和 strut2-dojo-plugin。 7. **结果类型**:Struts2支持多种结果类型,如dispatcher(用于转发到JSP页面)、stream(用于处理文件...

    struts2核心技术整理

    Struts2拥有丰富的插件系统,如Struts2-dojo-plugin、Struts2-convention-plugin等,这些插件能快速扩展Struts2的功能,简化开发过程。 七、Ajax支持 Struts2内建对Ajax的支持,可以通过`<s:a>`标签的`ajax="true...

    struts2经典demo

    5. **Interceptor使用**:可能有一些预定义的Interceptor如`logger`和`validation`,用于日志和表单验证,也可能是自定义的Interceptor,展示了如何扩展Struts2的功能。 6. **依赖的jar包**:Struts2运行所需的库,...

    struts2-apps

    6. **插件示例**:Struts2有许多社区贡献的插件,如JSON、Ajax、PDF等,这些插件可以扩展Struts2的功能。示例可能会展示如何使用和配置这些插件。 7. **RESTful服务**:Struts2也可以创建RESTful服务,示例可能包含...

    struts2深入详解源码1-5章

    插件机制则允许开发者轻松扩展Struts2的功能;整合其他框架能更好地利用已有资源,提高开发效率。 总的来说,这个资料包提供的源码分析涵盖了Struts2的基本架构、核心组件、高级特性和实际应用,是学习和理解Struts...

    精通struts2

    - **拦截器技术**(第4章):介绍了Struts2中的拦截器机制,这是一种用于扩展Struts2核心功能的重要技术。通过自定义拦截器,开发者可以根据实际需求对请求进行预处理或后处理。 - **返回类型(Result)**(第5章...

    struts2开源代码

    Struts2是一个强大的Java web应用程序开发...同时,你还可以了解到如何扩展Struts2以满足特定需求,比如自定义拦截器、结果类型等。这将有助于提升你的Java web开发技能,并让你更熟练地运用Struts2框架进行项目开发。

    struts2基本jar包

    以上jar包是构建Struts2应用程序的基础,开发者可以根据实际需求选择其他插件,如Spring整合插件、Struts2 jQuery插件等,以扩展Struts2的功能。正确地引入和配置这些jar包,可以有效地提高开发效率,同时保证应用的...

    最新Struts2开源实例代码以及Struts2源码

    通过阅读源码,可以更好地理解如如何定义和实现自定义拦截器、如何处理异常、如何扩展Struts2的功能等高级主题。此外,源码还包含了各种内置的插件和标签库,比如Tiles和FreeMarker,这些都是构建复杂Web界面的重要...

    Struts2知识点总结

    用户也可以根据自己的需求,自定义拦截器来扩展Struts2的功能。 在实际开发中,Struts2提供了一套约定优于配置的设计哲学,使得开发者不需要编写大量的配置代码即可快速搭建Web应用程序。当然,Struts2也支持复杂的...

    struts2源码分析总结

    `Dispatcher`还负责初始化插件,这些插件可以扩展Struts2的功能,例如类型转换、结果渲染等。 总的来说,Struts2的初始化过程涉及了日志、配置解析、ActionContext管理等多个重要环节,这些都为处理HTTP请求做好了...

    Struts2源代码 包含struts-core和xwork-core源码

    - 有助于自定义或扩展Struts2的功能,满足特定项目需求。 在实际开发中,了解这两个库的源代码可以帮助开发者更有效地利用Struts2,避免一些常见的陷阱,同时提高应用程序的性能和可维护性。通过深入学习,开发者...

    Struts2的输入校验

    虽然具体实现未在描述中详细说明,但通常这样的工具可能提供更便捷的验证方式,例如扩展Struts2的验证功能,或者提供更丰富的验证规则。 **最佳实践** 为了优化Struts2的输入校验,开发者应遵循以下最佳实践: - 尽...

    Struts2.2.1关键jar包

    8. **Plug-in机制**:Struts2支持插件化开发,如描述中提及的"插件包",开发者可以通过编写插件扩展Struts2的功能,比如国际化、验证码、上传下载等。 9. **Struts2的jar包**:压缩包中的jar文件可能包括Struts2的...

    struts2+spring+springstruts2+spring+springstruts2+spring+spring

    - **插件系统**:通过插件可以轻松地扩展Struts2的功能,比如集成Spring或Hibernate。 ### Spring框架 Spring框架是由Rod Johnson创建的轻量级控制反转(IoC)和面向切面编程(AOP)容器,主要目的是简化企业级...

    struts2配置文件加载顺序

    插件可以扩展Struts2的功能,如ognl、tiles等。 3. **struts.properties**:这是一个属性文件,通常位于项目的类路径根目录下,用于配置全局属性,比如常量定义、错误页面等。 4. **struts.xml**:这是用户自定义...

    struts2中常用jar包

    - **struts2-plugins/*.jar**:其他插件,如json、tiles、file-upload等,扩展Struts2功能。 - **ognl.jar**:Object-Graph Navigation Language,用于在Action和视图间传递数据。 - **xwork-core.jar**:XWork...

Global site tag (gtag.js) - Google Analytics