`

扩展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实现的!内付详细说明及范例,此方法仅为团队...

    Struts2 in action中文版

    第12章 使用插件扩展Struts 2 264 12.1 插件概要 264 12.2 常用插件 265 12.2.1 SiteMesh 266 12.2.2 Tiles 267 12.2.3 JFreeChart 269 12.3 内部组件系统 271 12.3.1 Bean 271 12.3.2 常量 272 12.3.3 注入 272 ...

    使用freemarker扩展struts标签

    使用struts2的freemarker模板扩展struts标签

    struts2技术内幕+struts2权威指南

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象

    struts2 技术内幕——深入解析struts2架构设计

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    Struts1与Struts2本质区别

    为了脱离Web容器测试Struts 1的Action,必须借助于第三方扩展:Struts TestCase,该扩展下包含了系列的Mock对象(模拟了HttpServetRequest和HttpServletResponse对象),从而可以脱离Web容器测试Struts 1的Action类...

    struts2的一些扩展用法

    NULL 博文链接:https://it-palmer.iteye.com/blog/1948253

    Struts2 技术内幕-深入解析Struts2架构设计与实现原理

    内容简介 出版日期: 2012年1月10日 《Struts2技术内幕:深入解析Struts2架构...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    扩展Struts示例程序的代码

    使用一个Struts应用的示例来示范如何使用这三种方式来扩展Struts。两个扩展Struts成功的范例是Struts自身的Validation和Tiles框架 用到了Hibernate, Spring, Struts的结构 此源代码教程: ...

    Struts2技术内幕.pdf

    本书由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    struts2+spring+velocity扩展实例V1版本

    struts2+spring+velocity简单的扩展实例,下载下来就能运行。后续将整合各项技术。敬请期待。

    Struts2返回JSON对象的方法总结完整实例

    但是,在开发工作中,对功能的升级是基于既定架构是很常见的情况。本人碰到需要用开发基于Struts2的HTTP+JSON返回类型接口就是基于既定框架结构下进行的。 Struts2返回JSON有两种方式:...2.使用Struts2对JSON的扩展。

    利用Turbine的事件映射来扩展Struts的功能.doc

    利用Turbine的事件映射来扩展Struts的功能.doc

    Struts2百度百科

    Struts2Apache Struts2是一个优雅的,可扩展的JAVA EE web框架。框架设计的目标贯穿整个开发周期,从开发到发布,包括维护的整个过程。

    Struts2+hibernate+spring的常见面试题

    1、什么是Struts2 Apache Struts2的是一个在Java中构建Web应用程序开源框架。 Struts2是基于OpenSymphony的WebWork的框架。它是Struts1的提高,它更加灵活,易于使用和扩展。 Struts2的核心组成部分是Action,拦截器...

    Apache Struts 2 源码(struts-2.5.28.3-src.zip)

    Apache Struts 2 源码(struts-2.5.28.3-src.zip),Apache Struts 2.5.28.3是一个优雅的、可扩展的框架,用于创建企业级 Java Web 应用程序。它可以在完整发行版中使用,也可以作为单独的库、源代码、示例和文档...

    Apache Struts 2 文档(struts-2.5.28.3-docs.zip)

    Apache Struts 2 文档(struts-2.5.28.3-docs.zip),Apache Struts 2.5.28.3是一个优雅的、可扩展的框架,用于创建企业级 Java Web 应用程序。它可以在完整发行版中使用,也可以作为单独的库、源代码、示例和文档...

    使用Struts2开发Java_Web应用程序

    第一章 Struts2 概览 Struts 是什么? Struts 2 是一个雅致的,可扩展的,用来建立企业级Java Web应用程序的框架。 Struts 2 不但注重程序的开发过程,更注重部署和后期维护。 Struts 2 来源于WebWork 2。 ...

Global site tag (gtag.js) - Google Analytics