详解Webwork中Action 调用的方法
本文主要通过三个方面给大家介绍webwork action调用相关知识,三个方面分别是
1.这部分框架类关系
2.Webwork 获取和包装 web 参数
3.DefaultActionProxyFactory、DefaultActionProxy、DefaultActionInvocation
一路走来,终于要开始 webwork 核心业务类的,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork 框架流转图中红色框的地方。
1.这部分框架类关系
2.Webwork 获取和包装 web 参数
•每个Web 框架或多或少的对 Web 请求参数的包装,用来拿来方便自己使用,webwork 也不例外。
•Webwork 每次响应请求的入口方法
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { if (encoding != null) { try { request.setCharacterEncoding(encoding); } catch (Exception localException) { } } if (locale != null) { response.setLocale(locale); } if (this.paramsWorkaroundEnabled) { request.getParameter("foo"); } request = wrapRequest(request); //封装 request请求 serviceAction(request, response, getNameSpace(request), getActionName(request), getRequestMap(request), getParameterMap(request), getSessionMap(request), getApplicationMap()); } catch (IOException e) { String message = "Could not wrap servlet request with MultipartRequestWrapper!"; log.error(message, e); sendError(request, response, , new ServletException(message, e)); } }
•接受 request 、response 参数,并对 request 参数进行封装,这次封装主要是针对多媒体请求进行的特殊处理,例如项目中的文件上传请求,导出各种类型文件等...
•包装完 request 之后,service 方法调用 ServletDispatche.serviceAction() 方法,并调用 getApplicationMap、getSessionMap、getRequestMap、 getParameterMap、getActionName、getNameSpace 6 个方法开始了Action 业务逻辑调用前的前戏。
•getNameSpace 方法用来获得一个Action所属的名称空间,例如 "/my/MyAction.action"则返回"/my",具体实现如下
protected String getNameSpace(HttpServletRequest request){ String servletPath = request.getServletPath(); return getNamespaceFromServletPath(servletPath); } public static String getNamespaceFromServletPath(String servletPath){ servletPath = servletPath.substring(, servletPath.lastIndexOf("/")); return servletPath; }
•getActionName 返回请求的Action的名字,例如"MyAction.action"则返回"MyAction",具体实现如下
protected String getActionName(HttpServletRequest request){ String servletPath = (String)request.getAttribute("javax.servlet.include.servlet_path"); if (servletPath == null) { servletPath = request.getServletPath(); } return getActionName(servletPath); } protected String getActionName(String name){ int beginIdx = name.lastIndexOf("/"); int endIdx = name.lastIndexOf("."); return name.substring(beginIdx == - ? : beginIdx + , endIdx == - ? name.length() : endIdx); }
• getRequestMap 方法返回一个包含请求中所有属性的Map,具体实现类是 RequestMap,具体代码如下
protected Map getRequestMap(HttpServletRequest request){ return new RequestMap(request); }
•getParameterMap 方法返回一个包含请求中所有参数的Map,具体代码如下
protected Map getParameterMap(HttpServletRequest request) throws IOException{ return request.getParameterMap(); }
•getSessionMap 方法返回一个包含 session 中所有属性的 Map,具体实现类是 SessionMap,具体代码如下
protected Map getSessionMap(HttpServletRequest request){ return new SessionMap(request); }
•getApplicationMap 方法返回一个包含 Application 中所有属性的Map,具体实现类 是ApplicationMap,具体代码如下
protected Map getApplicationMap(){ return new ApplicationMap(getServletContext()); }
•WebWork之所以要把request 的属性、参数,session 中的属性,Application 中的属性封装成 Map,仅仅是为了自己使用方便。
public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) { HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig()); extraContext.put(".opensymphony.xwork.dispatcher.ServletDispatcher", this); OgnlValueStack stack = (OgnlValueStack) request.getAttribute("webwork.valueStack"); if (stack != null) { extraContext.put(".opensymphony.xwork.util.OgnlValueStack.ValueStack", new OgnlValueStack(stack)); } try { ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext); request.setAttribute("webwork.valueStack", proxy.getInvocation().getStack()); proxy.execute(); if (stack != null) { request.setAttribute("webwork.valueStack", stack); } } catch (ConfigurationException e) { log.error("Could not find action", e); sendError(request, response, 404, e); } catch (Exception e) { log.error("Could not execute action", e); sendError(request, response, 500, e); } }
• ServiceAction 调用了createContextMap 创建Action 上下文(extraContext)。 它将JavaServlet 相关的对象进行包装,放入extraContext Map对象里。
•接着检查 上一个请求中是否有可用的值堆栈,如果有就放入extraContext 这个Map 对象里,供本次请求使用 。
•ActionContext(.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文 可以看作是一个容器(其实我们这里的容器就是一个Map 而已),它存放的是Action 在执行时需要用到的对象。
• ServletActionContext ( .opensymphony.webwork. ServletActionContext),这个类直接继承了ActionContext,它提供了直接与JavaServlet 相关象访问的功能。
•OgnlValueStack主要的功能是通过表达式语言来存取对象的属性。
3.DefaultActionProxyFactory、DefaultActionProxy、DefaultActionInvocation
前戏终于做完了,Action 调用的三兄弟要登场进行最重要的操作了,就是狼蚁网站SEO优化这三句代码,与Webwork 学习之路(五)请求跳转前 xwork.xml 的读取代码有非常相似的写法和设计
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext); request.setAttribute("webwork.valueStack", proxy.getInvocation().getStack());
proxy.execute(); •通过由前面获得的namespace、actionName、extraContext 创建调用代理 ActonProxy 实例,这里也就是 DefaultActionProxy,之后调用 了 ActionProxy.execute 方法来执行我们逻辑Action.execute。
•ActionProxy是一个接口,ActionProxyFactory则是一个抽象类,默认情况下它们是通过 DefaultActionProxy和DefaultActionProxyFactory来完成操作的。
•在 ActionProxyFactory 中有一个静态变量 factory ,它指向的是一个 DefaultActionProxyFactory 实例,代码如下:
static ActionProxyFactory factory = new DefaultActionProxyFactory(); public static void setFactory(ActionProxyFactory factory){ factory = factory; } public static ActionProxyFactory getFactory(){ return factory; }
• DefaultActionProxyFactory 的 createActionProxy 方法返回了 DefaultActionProxy 实例。
public ActionProxy createActionProxy(String namespace, String actionName, Map extraContext)throws Exception { setupConfigIfActionIsCommand(namespace, actionName); return new DefaultActionProxy(namespace, actionName, extraContext, true); } •DefaultActionProxy的构造函数 protected DefaultActionProxy(String namespace, String actionName, Map extraContext, boolean executeResult) throws Exception{ if (LOG.isDebugEnabled()) { LOG.debug("Creating an DefaultActionProxy for namespace " + namespace + " and action name " + actionName); } this.actionName = actionName; this.namespace = namespace; this.executeResult = executeResult; this.extraContext = extraContext; this.config = ConfigurationManager.getConfiguration().getRuntimeConfiguration().getActionConfig(namespace, actionName); if (this.config == null) { String message; String message; if ((namespace != null) && (namespace.trim().length() > 0)) { message = LocalizedTextUtil.findDefaultText("xwork.exception.missing-package-action", Locale.getDefault(), new String[] { namespace, actionName }); } else { message = LocalizedTextUtil.findDefaultText("xwork.exception.missing-action", Locale.getDefault(), new String[] { actionName }); } throw new ConfigurationException(message); } prepare(); }
•将传入的名称空间、 Action 的名字等参数赋予本地变量,接着通过 ConfigurationManager 获得当前请求的 Action 的配置信息[这里在5中已经描述过]。接着调用自身的 prepare 方法创建一个 ActionInvocation 对象赋予自身变量 invocation。在之后的 execute 方法中通过操纵invocation 来实现我们自己写的Action 的调用。
protected void prepare() throws Exception { this.invocation = ActionProxyFactory.getFactory().createActionInvocation(this, this.extraContext); }
以上所示是针对Webwork中Action 调用 的相关知识,希望对大家有所帮助。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程