- 浏览: 801985 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (120)
- Spring (10)
- ExtJs (2)
- Struts (15)
- Hibernate (4)
- 数据库 (2)
- Java (7)
- JSP (4)
- JavaScript (7)
- Oracle (5)
- 面试总结(收集的) (0)
- XML (3)
- 常用小技巧 (8)
- Ruby On Rails (4)
- JBPM (1)
- hsqldb (1)
- Java与模式 (5)
- Linux (5)
- WebLogic (2)
- FreeMarker (1)
- Android (1)
- PHP (1)
- Lucene (9)
- WebService----CXF (9)
- DB2 (4)
- MyBatis (1)
- JVM (3)
- GIT (1)
- JMS及ActiveMQ (4)
- Shiro (1)
最新评论
-
yadongliang:
楼主,我的地址栏http://localhost:8080/p ...
CXF之三(REST风格的支持) -
wangyudong:
由CXF实现的微服务需要有比较好的工具去测试RESTful A ...
CXF之三(REST风格的支持) -
renguoliang0508:
renguoliang0508 写道你好,我又来了,按你这里的 ...
CXF之六(对请求参数和返回给客户数据处理) -
renguoliang0508:
你好,我又来了,按你这里的实现。POST形式中获取不到参数。请 ...
CXF之六(对请求参数和返回给客户数据处理) -
renguoliang0508:
首先对您标示感谢,从拦截器的实现那篇参照做的,过程有点异常最终 ...
CXF之六(对请求参数和返回给客户数据处理)
第二篇 struts的执行
本篇详细介绍struts在初始化之后是如何处理一个请求,并返回数据的。这里最核心的类是RequestProcessor以及 RequestUtils。RequestProcessor类通过RequestDispatcher实现页面的跳转,而 RequestProcessor负责处理request中传来的请求信息,存放到FormBeanConfig中,以及对要跳转的url进行处理。
第二篇 struts的执行
struts 在初始化完成之后,会根据请求调用doGet(...)或者doPost(...)方法,这两个方法直接
调用process(request, response)方法。process(...)方法首先判断当前的request属于
哪一个ModuleConfig,然后生成与这个ModuleConifg相对应的RequestProcessor,最后调用这个
RequestProcessor的process(...)方法,执行request的请求。
一、RequestUtils.selectModule(String prefix, HttpServletRequest,ServletContext)方法:
这个方法,根据prefix,从ServletContext中选择相应的ModuleConfig,然后把这个ModuleConfig保存到 request中。ServletContext对应的key值为Globals.MODULE_KEY + prefix,保存到request中使用的key值为Globals.MODULE_KEY。如果在ServletContext中不存在这样的一个 ModuleConfig,那么调用request.removeAttribute(Globals.MODULE_KEY)方法。然后以同样的方法查找、保存MessageResources对象。当prefix为空时,会调用下面的方法选择ModuleConfig。
二、RequestUtils.selectModule(HttpServletRequest, ServletContext)
这个方发首先使用getModuleName(HttpServletRequest, ServletContext)获取相应的path,然后通过调用getModuleName(String matchPath, ServletContext)获取相应的prefix。以这prefix为参数调用(一)中的selectModule(...)选择 ModuleConfig。获取path的过程为:首先从request中查找名称为 INCLUDE_SERVLET_PATH(javax.servlet.include.servlet_path)的属性,如果为空,就调用 request.getServletPath()方法获取servletPath。
获取prefix的过程为:它首先调用getModulePrefixes(ServletContext),获取所有已存在的module前缀。然后通过分析上面获取的path来判断当前的url属于哪一个module,方法是截取path中最后一个"/"字符前面的字符串,然后与有上面方法中获取的prefixes[]逐个对比,如果prefixes[]中存在这样的一个值,则返回这个截取的字符串,否则继续截取path最后面的"/"前面的字符串,然后对比。如果始终找不到,则返回""。
getModulePrefixes(ServletContext)的执行过程是:首先通过 context.getAttribute(PREFIXES_KEY)查找是否存在这样的一个保存所有的prefix的string array,如果存在,就说明已经解析过一次了,就直接返回这个string array,否则遍历ServletContext中所有的attribute name,查找以MODULE_KEY(org.apache.struts.action.MODULE)开头的name,然后截取这个 atrribute name中MODULE_KEY后面的字符串,作为一个prefix. 最后把通过这个这个方式获取的所有的prefix作为一个ArrayList存储到ServletContext中,属性key值为 PREFIXES_KEY(org.apache.struts.util.PREFIXES),这样下次再次查找的时候就可以直接从这个 attribute中获取了。
三、getModuleConfig(HttpServletRequest)
这个方法就是获取上面的selectModule(...)方法所得到的ModuleConfig。如果找不到这样的ModuleConfig,那么就把 ServletContext中缺省的ModuleConfig返回(调用 getServletContext().getAttribute(Globals.MODULE_KEY))
四、getRequestProcessor(ModuleConfig config)
这个方法从根据ModuleConfig的prefix作为key,从ServletContext中获取RequestProcessor。这个key 值为Globals.REQUEST_PROCESSOR_KEY + config.getPrefix()。如果ServletContext中不存在这样的一个RequestProcessor,那么就生成一个新的 RequestProcessor的实例,完成初始化(保存ActionServlet以及ModuleConfig到这个新的实例中)后将其保存到 ServletContext中。
五、RequestProcessor.process(HttpServletRequest, HttpServletResponse)
这是真正执行HttpServletRequst请求的方法。这个方法首先判断但前的HttpServletRequest是否是Multipart类型的request,也就是说当前的request是否有字段是"file"类型。这样做的原因是这种类型的request中getParameter() 等相类似的方法都是无法执行的,所以要区分对待。如果是Multipart类型的,那么把这个request包装成 MultipartRequestWrapper类。MultipartRequestWrapper 与 HttpServletRequest不同的就是重新实现了setParameter(String name, String value),getParameter(String name),getParameterNames()以及getParameterValues(String name)方法。这些方法的思想是所有的变量名、值对都保存到一个HashMap里:key为变量名,value为变量值,但是注意value都是 String[]格式的。当有一个新的值加入的时候,通过setParameter(...)方法,把值加到数组的最后。在 setParameter(...)中有一个比较少见的保存值的方法,记录如下:
public void setParameter(String name, String value) {
String[] mValue = (String[]) parameters.get(name);
if (mValue == null) {
mValue = new String[0];
}
String[] newValue = new String[mValue.length + 1];
System.arraycopy(mValue, 0, newValue, 0, mValue.length);
newValue[mValue.length] = value;
parameters.put(name, newValue);
}
然后是调用processPath(HttpServletRequest, HttpServletResponse)获取地址,以这个地址作为从ModuleConfig获取ActionMapping的Key。这里首先查询 request.getAttribute(INCLUDE_PATH_INFO)中是否有这样的一个值,如果为空就调用 request.getPathInfo()方法获取path。如果这样还是获取不了,就从 request.getAttribute(INCLUDE_SERVLET_PATH)方法中获取path,找不到就使用 request.getServletPath()得到的path进行分析。分析过程如下:
然后如果这个path不是属于当前的ModuleConfig的话,直接返回null。截取prefix后面的字符串,如果这个字符串以.XX结尾,那么就截取"."前面的字符,比如http://localhost:8080/servlet/where/go.do 。where为module的名称(prefix),那么我们获取的path值为/go。
然后是通过processLocale(HttpServletRequest ,HttpServletResponse)为当前用户设定一个Local对象,它查找的顺序是:moduleConfig.getControllerConfig().getLocale(),session.getAttribute(Globals.LOCALE_KEY),request.getLocale()。你可以在config XML文件中通过<controller><set-property..../></controller>执行相关的定义。
调用processContent(HttpServletRequest, HttpServletResponse)为response设定contentType。这个contentType是从 moduleConfig.getControllerConfig().getContentType()获取的。你可以在config XML文件中通过<controller><set-property..../></controller>执行相关的定义。
通过processNoCache(HttpServletRequest, HttpServletResponse)方法设置response的缓存。你可以在config XML文件中通过<controller><set-property..../></controller>执行相关的定义。
processPreprocess(HttpServletRequest, HttpServletResponse)预处理request,这个方法是预留的,用户可以根据自己的需要加一些预处理的程序。
通过processMapping(HttpServletRequest, HttpServletResponse, String path)以processPath(...)的返回值为key从ModuleConfig中查找ActionMapping 对象。如果找到了,那么保存这个Mapping到request中,key值为Globals.MAPPING_KEY。如果不存在,那么遍历 ModuleConfig中所有的ActionMapping,查找哪一个是缺省的ActionMapping。然后把它保存到request中,key 值为Globals.MAPPING_KEY。
通过processRoles(HttpServletRequest,HttpServletResponse,ActionMapping)检查当前用户是否有权限执行这个请求。如果request.isUserInRole(roles[i])返回true,则代表有。
通过processActionForm(HttpServletRequest, HttpServletResponse, ActionMapping)生成一个ActionForm,然后根据ActionMapping所属的scope,保存到request或者 session中。key值为这个ActionMapping中的attribute属性。ActionForm是通过 RequestUtils.createActionForm(...)方法获取的,在下一篇将会对这个方法进行详细的说明。这里只说明 ActionForm与FormBeanConfig以及FormPropertyConfig之间的区别。每个FormPropertyConfig代表Form表单的一个字段,表单中的所有FormPropertyConfig以一个HashMap保存到FormBeanConfig中。而 FormBeanConfig是在Actionservet初始化的时候生成的:
<form-beans>
<form-bean name="一个名称,作为action选择的key" type="实际对应的ActionForm类"/>
<form-beans>
名称用来在MoudleConfig中的formBeans HashMap中查找相应的FormBeanConfig,而FormBeanConfig中有一个type,它保存了上面XML文件中定义的值,用来生成ActionForm。
通过processPopulate(HttpServletRequest, HttpServletResponse, ActionForm,ActionMapping)方法初始化ActionForm 以及 FormBean,这个方法首先会设定这个ActionForm所属于的ActionServlet,然后对这个ActionForm进行初始化。判断当前的reqest是否Multipart类型,如果是就把相应的MultipartClass类全名保存到request中,key值为 Globals.MULTIPART_KEY。调用RequestUtils.populate(...)对request中的参数进行处理,并保存到相应的FormBean中。在下一篇将会对这个方法进行详细的说明。最后根据request的parameter判断当前的请求是否是被取消,然后把相关信息保存到request中:
if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
(request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) {
request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
}
六、下面说明这个request是如何真正被处理的,下面的方法都是在RequestProcessor中定义
通过processValidate(HttpServletRequest, HttpServletResponse, ActionForm,ActionMapping)判断request中的parameter是否合法。如果合法就返回true,否则取消这次请求,并且返回到指定的输入页面。它判断合法的过程是:如果这次的请求被取消,那么直接返回true;如果没有要求对request中的parameter进行合法性检验,也直接返回true;最后通过调用form.validate(mapping, request)执行检验,如果返回的ActionErrors为null,那么代表通过检验,返回true,否则取消这次request。取消的过程是:如果这个请求是Multipart类型的,那么要对这个MultipartRequestHandler进行回滚;而后,获取当前的 ActionMapping的input值,即在config XML 中<action.../>定义的input属性。如果ActionMapping没有这个input值,那么调用 response.sendError(...)方法,然后返回false;如果存在,就保存验证出错信息到request中,key为 Globals.ERROR_KEY,跳转到input所指定的地址中。
processForward(HttpServletRequest, HttpServletResponse, ActionMapping)以及processInclude(HttpServletRequest, HttpServletResponse, ActionMapping)分别通过执行RequestDispatcher.forward(request, response) 以及 RequestDispatcher.include(request, response)实现对页面的跳转。
但是如果当前的请求还有其它操作要执行,那么ActionMapping中的include或者forward属性值就会为空。这时需要通过调用 processActionCreate(HttpServletRequest, HttpServletResponse, ActionMapping)方法根据config XML文件的配置信息生成一个Action类,然后通过processActionPerform(...)调用生成的Action中的 execute(...)方法。最后根据execute(...)方法返回的ActionForword类,执行跳转。在整个过程中有一个url的计算方法,这个将在下一篇中说明。
七、对ActionMaping结构的说明:
在ActionConfig为保存Moudle Action属性的一个javabean,它有以下属性:
* boolean configured 这个对象的所有属性是否已经被配置完。如果已经完成,那么在改变其中任何属性都会抛出IllegalStateException("Configuration is frozen")
* ModuleConfig moduleConfig 本ActionConfig类所属于的ModuleConfig。
* String attribute request范围 或者 session范围 的属性名称,我们将通过这个属性名称来获取相应的form bean,注意,这个属性与form bean中定义的名称是不一样的。注意以下的方法:
public String getAttribute() {
if (this.attribute == null) {
return (this.name);
} else {
return (this.attribute);
}
}
* String forward 调用RequestDispatcher.forward()方法时所需要的上下文相关的地址。
* String include 调用RequestDispatcher.include()方法时所需要的上下文相关的地址。
* String type Action类的类全名,如果上面的两个属性都没有定义的话,就会用它来处理request。
* String input 如果输入数据没有通过验证,将会以这个值为地址,跳转到相应的页面。
* String multipartClass MultipartRequestHandler实现类的全名
* String name 与本类相关的 form bean 的名称。
* String parameter 用于struts的扩展,存储其它的配置信息。struts自己不会用到这个属性。
* String path 上下文相关的地址,这个地址为下一个将会进入的地址,这个地址必须要以"/"开头。如果使用了extension mapping的话,这个地址将不会带有扩展名。
* String roles 一个以","分隔的角色名称。这些角色将会有权限访问这个request。
* String scope 缺省为session。
* String prefix,String suffix后缀和前缀。
* boolean unknown 标志当前的ActionConfig类是否是为了未知的request path而准备的,ActionMappings将会根据这个标志返回这个ActionConfig。
* boolean validate 是否调用validate()方法进行数据校验。
ActionMapping 继承自 ActionConfig,它增加了从ModuleConfig查找ActionForword的方法。同时它还提供了从ModuleConfig查找 ExceptionConfig的方法,如果找不到,会通过type.getSuperclass()方法,根据父类的类名称继续查找,直到最后。
八、关于request.getServletPath()的解释:
request.getServletPath() 的返回值就是在下面url中定义的值,比如如果按照下面的定义
<url-pattern>
*.do
</url-pattern>
那么:
http://localhost:8080/servlet/go.do ---------->/go.do
http://localhost:8080/servlet/where/go.do ---------->/where/go.do
如果
<url-pattern>
/where/*.do
</url-pattern>
那么地址中只有http://localhost:8080/servlet/where/*.do 有效(tomcat 4.0)
如果
<url-pattern>
/where/*
</url-pattern>
那么:
http://localhost:8080/servlet/where/go/ ---------->servletPath为/where, pathInfo为/go/
发表评论
-
精通struts技术之 ServletContext
2009-08-07 15:37 2231ServletContext是定义在javax.servlet ... -
HttpSessionListener 和HttpSessionBindingListener的区别
2009-08-04 08:49 2273使用HttpSessionListener编写一个Onlin ... -
使用HttpSessionBindingListener 方法
2009-08-04 08:47 14668捕获Session事件的意义: 1、 记录网站的客户登录 ... -
web.xml中load-on-startup标签的含义
2009-07-31 09:11 1336在servlet的配置当中,<load-on-start ... -
使用Struts的PlugIn进行Web应用的扩展
2009-07-31 09:02 1324Struts提供了PlugIn的方式来扩展Struts的功 ... -
RequestProcessor及其在struts-config.xml中的配置
2009-07-30 17:37 1677RequestProcessor及其在struts-confi ... -
Struts1.整合Spring的三种方法
2009-06-23 13:37 1537使用 Spring 的 ActionSupport 类 ... -
struts使用list提交多行表单
2009-06-13 11:23 2882在struts框架中常常会遇到多行表单的情况, 如何有效的利用 ... -
五个有用的过滤器 Filter
2009-06-13 11:22 1188一、使浏览器不缓存页面的过滤器 import java ... -
利用令牌机制解决重复重复提交问题
2009-06-13 10:53 2077用Token解决重复重复提交:Struts利用同步令牌(Tok ... -
log4j的日志处理
2009-05-08 11:20 1701在日常的开发中经常需要通过输出一些信息进行程序的 ... -
Struts2中使用request,response对象方法
2009-05-07 14:05 1494***************1.[一般推荐使用](只能获得r ... -
Struts2中多次提交问题
2009-05-07 14:02 1361struts.xml如下: <?xml version= ... -
struts1的工作流程
2009-04-29 10:43 1753在web应用启动时就会加载初始化ActionServlet,A ...
相关推荐
Struts Plugin是一个专门为Apache Struts框架设计的组件,它扩展了框架的功能,使得开发者能够更加高效、灵活地构建Web应用程序。Struts是一个基于MVC(Model-View-Controller)设计模式的Java EE(Enterprise ...
赠送jar包:struts2-json-plugin-2.3.24.jar; 赠送原API文档:struts2-json-plugin-2.3.24-javadoc.jar; 赠送源代码:struts2-json-plugin-2.3.24-sources.jar; 赠送Maven依赖信息文件:struts2-json-plugin-...
struts2-json-plugin,Struts JSON插件
Struts2 JSON Plugin是针对Apache Struts2框架的一个重要组件,版本为2.3.8。这个插件主要的功能是让Struts2应用程序能够轻松地处理JSON(JavaScript Object Notation)数据格式,使得Web应用可以方便地进行JSON序列...
struts2-ssl-plugin-1.2.1.jar
struts2-spring-plugin-2.3.15.2.jar ; struts2-json-plugin-2.3.16.3.jarstruts2-spring-plugin-2.3.15.2.jar ; struts2-json-plugin-2.3.16.3.jar
Struts2-dojo-plugin-2.2.1.jar 是一个针对Apache Struts2框架的扩展插件,主要用于增强Struts2应用的用户界面交互性,特别是通过集成Dojo JavaScript库来提供丰富的AJAX功能和用户体验。这个插件是Struts2与Dojo ...
struts2-struts1-plugin-2.1.6.jar
core-2.5.10.1.jar,struts2-jfreechart-plugin-2.5.10.1.jar,struts2-json-plugin-2.5.10.1.jar,struts2-junit-plugin-2.5.10.1.jar,struts2-bean-validation-plugin-2.5.10.1.jar,struts2-cdi-plugin-...
struts2 json plugin jar包
Struts2-Spring-Plugin-2.2.1.jar 是一个专门为 Struts2 框架与 Spring 框架集成而设计的插件。这个插件的主要目的是简化在基于Struts2的应用程序中整合Spring的功能,如依赖注入(DI)、AOP(面向切面编程)以及...
`struts2-json-plugin`是Struts2的一个插件,它使得Struts2能够处理JSON请求和响应,无需额外的配置或库。这个插件不仅包含了源码,还包含了必要的配置文件和类,使得开发者可以深入理解其工作原理并进行自定义扩展...
在Struts框架中,插件(Plugin)是扩展其功能的关键组件。"Struts plugin.htmleditor1.6" 指的可能是Struts的一个特定版本,1.6版的HTML编辑器插件,用于提供在Web应用中编辑HTML内容的功能。 HTML编辑器插件在...
最新struts2-struts1-plugin-2.1.8.1.jar
Struts2-Spring-Plugin-2.3.4.jar 是一个专门为 Struts 2 框架和 Spring 框架整合而设计的插件,主要用于处理 Struts 2 和 Spring 之间的集成问题。在Java Web开发中,这两个框架经常一起使用,Spring 提供了依赖...
- **Action代理**:使用Spring的Struts Plugin,创建一个Spring-aware的Action代理,将请求转发到Spring管理的Bean。 - **事务管理**:配置Spring的事务管理器,处理业务逻辑中的事务边界。 5. **Spring的...
struts2 spring plugin 2.3.32,用于漏洞修复
struts2-jquery-plugin-3.1.0.jar
Struts2-Spring-Plugin-2.2.3.jar 是一个专门为 Struts2 框架与 Spring 框架整合而设计的插件。在Java Web开发中,这两个框架都极其常见,Struts2 提供了MVC(模型-视图-控制器)架构模式,而Spring则是一个强大的...
在给定的压缩包文件中,我们关注的是"struts2-spring-plugin-2.2.1.jar",这是一个插件,它将Struts2框架与Spring框架集成。 Struts2 Spring Plugin是Struts2框架的一个重要组成部分,它的主要作用是允许开发者在...