- 浏览: 105087 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
BlueSkator:
bo_hai 写道rz -y 强制覆盖linux上的文件。
linux rz sz 命令 -
bo_hai:
rz -y 强制覆盖linux上的文件。
linux rz sz 命令 -
yoyo837:
我以为是原生ajax
ajax 三种提交请求的方法 -
BlueSkator:
jahu 写道火狐,使用不成功,写js代码注意,兼容性噢 火狐 ...
js 预提交请求时确定后提交实现 -
jahu:
火狐,使用不成功,写js代码注意,兼容性
js 预提交请求时确定后提交实现
Dispatcher类
Dispatcher类是在struts2中定义的,在 webwork2 中叫DispatcherUtils,
作用相同:
1 初始化模块参数,
2 将 xwork 于 web层分离,
3 中转请求,进入xwork 的 action处理流程。
1 初始化,涉及方法 init()
在上一篇的 FilterDispatcher中的init() 方法,有这么两句:
就是调用Dispatcher的初始化。
2 xwork 定义了一个类 : ActonContext,
ActonContext 有两个作用
1) 线程安全,
过这个类,xwork2 实现了 action 的线程安全,
为每一次的action请求, 分配一个独立的ActonContext。
2) 于 web 层分离,
xwork的做法,是把web层中组件中的变量
(主要是javax.servlet包中的类,如HttpServletRequest)
取出来,放入ActonContext。
这样xwork就不要在向外访问web层了。
涉及方法
- public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
- ActionMapping mapping, ServletContext context) {
Dispatcher 的这个方法,把web层的参数取出然后放入Map 中,(以备xwork构造ActionContext)。
3 中转请求,调action处理逻辑,这个是比较重要的一个地方,
- public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
- ActionMapping mapping) throws ServletException {
- Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
- // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
- ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
- if (stack != null ) {
- extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));
- }
- String timerKey = "Handling request from Dispatcher" ;
- try {
- UtilTimerStack.push(timerKey);
- String namespace = mapping.getNamespace();
- String name = mapping.getName();
- String method = mapping.getMethod();
- Configuration config = configurationManager.getConfiguration();
- ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory. class ).createActionProxy(
- namespace, name, extraContext, true , false );
- proxy.setMethod(method);
- request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
- // if the ActionMapping says to go straight to a result, do it!
- if (mapping.getResult() != null ) {
- Result result = mapping.getResult();
- result.execute(proxy.getInvocation());
- } else {
- proxy.execute();
- }
- // If there was a previous value stack then set it back onto the request
- if (stack != null ) {
- request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
- }
- } catch (ConfigurationException e) {
- LOG.error( "Could not find action or result" , e);
- sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
- } catch (Exception e) {
- throw new ServletException(e);
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, extraContext, true, false);
得到框架的配置信息,得到框架的Container,构造出 ActionProxy。
这个过程中,涉及到几个xwork较核心的类,Configuration, ConfigurationManager, Container,
Configuration, ConfigurationManager 负责框架配置信息初始化的类
- public class DefaultConfiguration implements Configuration {
- protected static final Logger LOG = LoggerFactory.getLogger(DefaultConfiguration. class );
- // Programmatic Action Configurations
- protected Map<String, PackageConfig> packageContexts = new LinkedHashMap<String, PackageConfig>();
- protected RuntimeConfiguration runtimeConfiguration;
- protected Container container;
- protected String defaultFrameworkBeanName;
- protected Set<String> loadedFileNames = new TreeSet<String>();
- ObjectFactory objectFactory;
这是描述框架总体配置信息的,其中,
Map<String, PackageConfig> 放的是package的config,对应struts2 配置文件中 package标签内容,
PackageConfig
- public class PackageConfig extends Located implements Comparable, Serializable, InterceptorLocator {
- private static final Logger LOG = LoggerFactory.getLogger(PackageConfig. class );
- private Map<String, ActionConfig> actionConfigs;
- private Map<String, ResultConfig> globalResultConfigs;
- private Map<String, Object> interceptorConfigs;
- private Map<String, ResultTypeConfig> resultTypeConfigs;
- private List<ExceptionMappingConfig> globalExceptionMappingConfigs;
- private List<PackageConfig> parents;
- private String defaultInterceptorRef;
- private String defaultActionRef;
- private String defaultResultType;
- private String defaultClassRef;
- private String name;
- private String namespace = "" ;
- private boolean isAbstract = false ;
- private boolean needsRefresh;
里边是一些package的信息,其中Map<String, ActionConfig> 放的就是action的描述类ActionConfig了
ActionConfig
- public class ActionConfig extends Located implements Serializable {
- public static final String WILDCARD = "*" ;
- protected List<InterceptorMapping> interceptors;
- protected Map<String, String> params;
- protected Map<String, ResultConfig> results;
- protected List<ExceptionMappingConfig> exceptionMappings;
- protected String className;
- protected String methodName;
- protected String packageName;
- protected String name;
- protected Set<String> allowedMethods;
其中
interceptors : action的拦截器,
results: action执行后用来收尾的,如,跳到定义好的页面。 className 类名,packageName 包名,methodName 默认是 execute。
框架一般有个必须要做的活,就是把某配置文件的信息读到框架系统中来,
xwork2中,XMLConfigurationProvider 就是干这个的,
他读xml配置文件(就是我们定义action的配置的那个文件),
然后把这些信息写到Configuration中。
ConfigurationManager 则负责调用适当的 ConfigurationProvider,
执行初始化逻辑,和返回具体的Configuration。
初始化等前期工作完毕后,则开始执行action的逻辑了,
xwork 使用了代理模式执行action,
proxy.execute();
从这一句起, strust2 就把工作交接给了xwork了。
接着看Dispatcher
- ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory. class ).createActionProxy(
- namespace, name, extraContext, true , false );
[java] view plain copy
- ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory. class ).createActionProxy(
- namespace, name, extraContext, true , false );
用Container 构造一个 ActionProxyFactory,在用ActionProxyFactory create一个 ActionProxy。
- public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) {
- ActionInvocation inv = new DefaultActionInvocation(extraContext, true );
- container.inject(inv);
- return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
- }
[java] view plain copy
- public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) {
- ActionInvocation inv = new DefaultActionInvocation(extraContext, true );
- container.inject(inv);
- return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
- }
xwork中,action的调用是借助 Proxy 模式,
Proxy 模式的实现,则是 DefaultActionProxy, Action, ActionInvocation 合伙完成的。
下边是一些关键代码
DefaultActionProxy
- public String execute() throws Exception {
- ActionContext nestedContext = ActionContext.getContext();
- ActionContext.setContext(invocation.getInvocationContext());
- String retCode = null ;
- String profileKey = "execute: " ;
- try {
- UtilTimerStack.push(profileKey);
- <SPAN style= "COLOR: #ff0000" > retCode = invocation.invoke();</SPAN>
- } finally {
- if (cleanupContext) {
- ActionContext.setContext(nestedContext);
- }
- UtilTimerStack.pop(profileKey);
- }
- return retCode;
- }
[java] view plain copy
- public String execute() throws Exception {
- ActionContext nestedContext = ActionContext.getContext();
- ActionContext.setContext(invocation.getInvocationContext());
- String retCode = null ;
- String profileKey = "execute: " ;
- try {
- UtilTimerStack.push(profileKey);
- <span style="color: #ff0000;" > retCode = invocation.invoke();</span>
- } finally {
- if (cleanupContext) {
- ActionContext.setContext(nestedContext);
- }
- UtilTimerStack.pop(profileKey);
- }
- return retCode;
- }
DefaultActionInvocation 得 invoke 方法。
- public String invoke() throws Exception {
- String profileKey = "invoke: " ;
- try {
- UtilTimerStack.push(profileKey);
- if (executed) {
- throw new IllegalStateException( "Action has already executed" );
- }
- if (interceptors.hasNext()) {
- final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
- UtilTimerStack.profile( "interceptor: " +interceptor.getName(),
- new UtilTimerStack.ProfilingBlock<String>() {
- public String doProfiling() throws Exception {
- <SPAN style= "COLOR: #ff0000" >resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation. this );</SPAN>
- return null ;
- }
- });
- } else {
- <SPAN style= "COLOR: #ff0000" >resultCode = invokeActionOnly();</SPAN>
- }
- // this is needed because the result will be executed, then control will return to the Interceptor, which will
- // return above and flow through again
- if (!executed) {
- if (preResultListeners != null ) {
- for (Iterator iterator = preResultListeners.iterator();
- iterator.hasNext();) {
- PreResultListener listener = (PreResultListener) iterator.next();
- String _profileKey= "preResultListener: " ;
- try {
- UtilTimerStack.push(_profileKey);
- listener.beforeResult( this , resultCode);
- }
- finally {
- UtilTimerStack.pop(_profileKey);
- }
- }
- }
- // now execute the result, if we're supposed to
- if (proxy.getExecuteResult()) {
- executeResult();
- }
- executed = true ;
- }
- return resultCode;
- }
- finally {
- UtilTimerStack.pop(profileKey);
- }
- }
[java] view plain copy
- public String invoke() throws Exception {
- String profileKey = "invoke: " ;
- try {
- UtilTimerStack.push(profileKey);
- if (executed) {
- throw new IllegalStateException( "Action has already executed" );
- }
- if (interceptors.hasNext()) {
- final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
- UtilTimerStack.profile("interceptor: " +interceptor.getName(),
- new UtilTimerStack.ProfilingBlock<String>() {
- public String doProfiling() throws Exception {
- <span style="color: #ff0000;" >resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation. this );</span>
- return null ;
- }
- });
- } else {
- <span style="color: #ff0000;" >resultCode = invokeActionOnly();</span>
- }
- // this is needed because the result will be executed, then control will return to the Interceptor, which will
- // return above and flow through again
- if (!executed) {
- if (preResultListeners != null ) {
- for (Iterator iterator = preResultListeners.iterator();
- iterator.hasNext();) {
- PreResultListener listener = (PreResultListener) iterator.next();
- String _profileKey="preResultListener: " ;
- try {
- UtilTimerStack.push(_profileKey);
- listener.beforeResult(this , resultCode);
- }
- finally {
- UtilTimerStack.pop(_profileKey);
- }
- }
- }
- // now execute the result, if we're supposed to
- if (proxy.getExecuteResult()) {
- executeResult();
- }
- executed = true ;
- }
- return resultCode;
- }
- finally {
- UtilTimerStack.pop(profileKey);
- }
- }
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); 是判断这个action是否有未被执行的拦截器,
resultCode = invokeActionOnly();
如没有或拦截器执行完毕,则执行invokeActionOnly
invokeActionOnly方法
- public String <SPAN style= "COLOR: #ff0000" >invokeActionOnly()</SPAN> throws Exception {
- return invokeAction(getAction(), proxy.getConfig());
- }
- rotected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
- String methodName = proxy.getMethod();
- if (LOG.isDebugEnabled()) {
- LOG.debug( "Executing action method = " + actionConfig.getMethodName());
- }
- String timerKey = "invokeAction: " +proxy.getActionName();
- try {
- UtilTimerStack.push(timerKey);
- boolean methodCalled = false ;
- Object methodResult = null ;
- Method method = null ;
- try {
- <SPAN style= "COLOR: #ff0000" >method = getAction().getClass().getMethod(methodName, new Class[ 0 ]);</SPAN>
- } catch (NoSuchMethodException e) {
- // hmm -- OK, try doXxx instead
- try {
- String altMethodName = "do" + methodName.substring( 0 , 1 ).toUpperCase() + methodName.substring( 1 );
- method = getAction().getClass().getMethod(altMethodName, new Class[ 0 ]);
- } catch (NoSuchMethodException e1) {
- // well, give the unknown handler a shot
- if (unknownHandler != null ) {
- try {
- methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);
- methodCalled = true ;
- } catch (NoSuchMethodException e2) {
- // throw the original one
- throw e;
- }
- } else {
- throw e;
- }
- }
- }
- if (!methodCalled) {
- <SPAN style= "COLOR: #ff0000" >methodResult = method.invoke(action, new Object[ 0 ]);</SPAN>
- }
- if (methodResult instanceof Result) {
- this .explicitResult = (Result) methodResult;
- return null ;
- } else {
- return (String) methodResult;
- }
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException( "The " + methodName + "() is not defined in action " + getAction().getClass() + "" );
- } catch (InvocationTargetException e) {
- // We try to return the source exception.
- Throwable t = e.getTargetException();
- if (actionEventListener != null ) {
- String result = actionEventListener.handleException(t, getStack());
- if (result != null ) {
- return result;
- }
- }
- if (t instanceof Exception) {
- throw (Exception) t;
- } else {
- throw e;
- }
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
[java] view plain copy
- public String <span style= "color: #ff0000;" >invokeActionOnly()</span> throws Exception {
- return invokeAction(getAction(), proxy.getConfig());
- }
- rotected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
- String methodName = proxy.getMethod();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Executing action method = " + actionConfig.getMethodName());
- }
- String timerKey = "invokeAction: " +proxy.getActionName();
- try {
- UtilTimerStack.push(timerKey);
- boolean methodCalled = false ;
- Object methodResult = null ;
- Method method = null ;
- try {
- <span style="color: #ff0000;" >method = getAction().getClass().getMethod(methodName, new Class[ 0 ]);</span>
- } catch (NoSuchMethodException e) {
- // hmm -- OK, try doXxx instead
- try {
- String altMethodName = "do" + methodName.substring( 0 , 1 ).toUpperCase() + methodName.substring( 1 );
- method = getAction().getClass().getMethod(altMethodName, new Class[ 0 ]);
- } catch (NoSuchMethodException e1) {
- // well, give the unknown handler a shot
- if (unknownHandler != null ) {
- try {
- methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);
- methodCalled = true ;
- } catch (NoSuchMethodException e2) {
- // throw the original one
- throw e;
- }
- } else {
- throw e;
- }
- }
- }
- if (!methodCalled) {
- <span style="color: #ff0000;" >methodResult = method.invoke(action, new Object[ 0 ]);</span>
- }
- if (methodResult instanceof Result) {
- this .explicitResult = (Result) methodResult;
- return null ;
- } else {
- return (String) methodResult;
- }
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException( "The " + methodName + "() is not defined in action " + getAction().getClass() + "" );
- } catch (InvocationTargetException e) {
- // We try to return the source exception.
- Throwable t = e.getTargetException();
- if (actionEventListener != null ) {
- String result = actionEventListener.handleException(t, getStack());
- if (result != null ) {
- return result;
- }
- }
- if (t instanceof Exception) {
- throw (Exception) t;
- } else {
- throw e;
- }
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
method = getAction().getClass().getMethod(methodName, new Class[0]); 取出需执行的action的方法,如 execute()
methodResult = method.invoke(action, new Object[0]); 利用反射,执行action 方法
上边就是利用proxy模式,调用一个action的具体逻辑 的 过程。
一般的action里,都有一些变量,如从request中取出的参数等,
如要执行action 方法,如execute(),则必须先吧这些变量赋值 已供方法中使用,
这个工作,就是 拦截器(Interceptor) 的任务之一,
下篇探讨一下拦截器。
发表评论
-
检查maven 项目jar包依赖是否冲突
2015-07-23 16:16 6828在项目发布的时候,一般都需要进行依赖冲突检查或者重复类的检 ... -
java 类加载顺序
2015-05-19 12:02 658加载顺序是: ... -
springmvc 中restful 的url 可能出现的问题
2015-01-19 11:27 904< url-pattern > / </ u ... -
注册表无法访问 解决方案
2015-01-18 13:55 1020可以采用下面的两种方法来解决该问题: 1、用组策略解决该 ... -
像打开QQ和迅雷一样在网站中点击打开本地的应用
2015-01-07 15:08 1493例子: 说到单点登录,往往是和Portal(门户) ... -
登录验证码的实现
2014-09-22 11:32 636import java.awt.Color; impor ... -
获取前n天的日期
2014-09-22 11:20 628public static String getNextFe ... -
j2ee 导出excel ,poi + jxl
2014-09-22 11:11 13931、POI 导出 Excel public static ... -
ajax 三种提交请求的方法
2014-09-22 11:04 84281、ajax 提交请求 $.ajax({ typ ... -
用debug模式启动tomcat出现 classNotFound ,无法启动服务器
2014-08-13 20:06 758解决方案:点击线程右键选择Resume 选项,然后即可重启 -
数据库中无数据时查询数据为空,但出现空指针异常的解决方案
2014-07-24 16:15 8321异常:java.lang.NullPointerExcep ... -
Invoking validate() on action Struts2 的验证问题
2014-07-23 22:20 612问题描述: 出现找不到Action且ActionMetho ... -
日历插件的应用
2014-07-23 21:07 7811、拷贝js到相应的目录 2、引入js <scri ... -
tomcat 造成的乱码原因与解决方案
2014-07-15 20:08 747只需在tomcat/conf/server.xml 中增加一 ... -
js 预提交请求时确定后提交实现
2014-07-15 20:04 1237<!DOCTYPE html PUBLIC " ... -
powerdesigner的应用
2014-07-09 15:00 9001、powerdesigner 生成sql脚本中 生成列名 ... -
VC6.0下显示行号
2013-09-29 02:47 841VC6.0是一款比较稳定的功能强大的IDE,目前也有很多人在 ... -
js返回上一页的脚本
2012-04-19 18:52 1147返回上一页js代码 ... -
第一次做myeclipse6.5 + struts2遇到的问题
2012-02-20 20:46 1408由于myeclipse7.0没有集成struts2,只 ... -
Struts2中struts.xml的Action、namespace配置详解
2012-02-20 20:43 2344今天做了个struts2练习,发现自己对struts.xml的 ...
相关推荐
源码学习,Xwork2 源码阅读.pdf webwork源码, strtus2 源码
NULL 博文链接:https://gutou9.iteye.com/blog/268794
xwork-2.1.2-all.zip,xwork2.2.1源码,github上下载,适合不会SVN下载的初学者
xwork2.1.6源码及其之前版本的源码
struts2下的xwork源码 学习源代码,掌握struts2原理
xwork-2.0.4源码 xwork2源码
struts2-core-2.3.1.2.jar 和xwork-core-2.3.1.2.jar的源码;
XWork源码+docs+showcase全,在运用struts2时可通过eclipse或myeclipse查看源码
Struts2中xwork源码,希望对你们有所帮助。
这个压缩包包含struts-xwork-core的src源码,导入eclipse即可。
xwork源码 xwork src Eclipse关联xwork源码 这个目录里面xwork-2.0.7\src\java
xwork源码及文档,xwork源码及文档,xwork源码及文档
xwork源码,xwork源码,xwork源码
Xwork的源码,struts2中action的内核
xwork 2.8的源码,最新版本欢迎下载!
Struts 2源码查看xwork-2.1.5第二部分 Struts 2源码查看xwork-2.1.5第二部分 Struts 2源码查看xwork-2.1.5第二部分
在网上找到的好东西,拿来大家共享一下。希望支持
xwork2.3.3 源码,解压后的文件就是源码,用exlipse加载方法,在xwork2.3.3.jar上右键--属性--java source Attachment,选择external folder把解压后的文件目录定位到Java即可,我的路径是F:/struts-2.3.3-src/src/...
xwork-2.0.4 源码 xwork-2.0.4 源码
使用SVN下载的xwork的源代码包,包含docs、src、core、plugins、assembly等文件,以及xwork.jar札包。