详解Webwork中Action 调用的方法


Posted in Javascript onFebruary 02, 2016

本文主要通过三个方面给大家介绍webwork action调用相关知识,三个方面分别是:

1.这部分框架类关系

2.Webwork 获取和包装 web 参数

3.DefaultActionProxyFactory、DefaultActionProxy、DefaultActionInvocation

一路走来,终于要开始 webwork 核心业务类的总结,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork 框架流转图中红色框的地方。

详解Webwork中Action 调用的方法

1.这部分框架类关系

详解Webwork中Action 调用的方法

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("com.opensymphony.xwork.dispatcher.ServletDispatcher", this);
OgnlValueStack stack = (OgnlValueStack) request.getAttribute("webwork.valueStack");
if (stack != null) {
extraContext.put("com.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(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文 可以看作是一个容器(其实我们这里的容器就是一个Map 而已),它存放的是Action 在执行时需要用到的对象。

• ServletActionContext ( com.opensymphony.webwork. ServletActionContext),这个类直接继承了ActionContext,它提供了直接与JavaServlet 相关象访问的功能。

•OgnlValueStack主要的功能是通过表达式语言来存取对象的属性。

3.DefaultActionProxyFactory、DefaultActionProxy、DefaultActionInvocation

前戏终于做完了,Action 调用的三兄弟要登场进行最重要的操作了,就是下面这三句代码,与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 调用 的相关知识,希望对大家有所帮助。

Javascript 相关文章推荐
一个简单的动态加载js和css的jquery代码
Sep 01 Javascript
JavaScript之数组(Array)详解
Apr 01 Javascript
JS+CSS实现带小三角指引的滑动门效果
Sep 22 Javascript
AngularJS 2.0新特性有哪些
Feb 18 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
Aug 19 Javascript
CSS3 3D 技术手把手教你玩转
Sep 02 Javascript
JavaScript实现DOM对象选择器
Sep 24 Javascript
Bootstrap基本插件学习笔记之Alert警告框(20)
Dec 08 Javascript
js实现文字向上轮播功能
Jan 13 Javascript
js以及jquery实现手风琴效果
Apr 17 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
Mar 21 jQuery
nuxt配置通过指定IP和端口访问的实现
Jan 08 Javascript
JavaScript File API文件上传预览
Feb 02 #Javascript
javascript绘制漂亮的心型线效果完整实例
Feb 02 #Javascript
Webwork 实现文件上传下载代码详解
Feb 02 #Javascript
javascript自动切换焦点控制效果完整实例
Feb 02 #Javascript
原生js实现图片层叠轮播切换效果
Feb 02 #Javascript
Javascript实现的SHA-256加密算法完整实例
Feb 02 #Javascript
JavaScript实现的SHA-1加密算法完整实例
Feb 02 #Javascript
You might like
PHP编码转换函数 自动转换字符集支持数组转换
2012/12/16 PHP
Alliance vs AM BO3 第二场2.13
2021/03/10 DOTA
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
JavaScript设计模式之代理模式介绍
2014/12/28 Javascript
Nodejs学习笔记之NET模块
2015/01/13 NodeJs
JQuery球队选择实例
2015/05/18 Javascript
js判断手机浏览器操作系统和微信浏览器的方法
2016/04/30 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
jQuery Mobile和HTML5开发App推广注册页
2016/11/07 Javascript
微信小程序 页面传参实例详解
2016/11/16 Javascript
NodeJS实现图片上传代码(Express)
2017/06/30 NodeJs
Vuex 快速入门(简单易懂)
2018/09/20 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
2019/06/11 Javascript
ES6中Symbol、Set和Map用法详解
2019/08/20 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
python获取当前时间对应unix时间戳的方法
2015/05/15 Python
python中常用的九种预处理方法分享
2016/09/11 Python
Python实现的密码强度检测器示例
2017/08/23 Python
NumPy 如何生成多维数组的方法
2018/02/05 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
python+openCV调用摄像头拍摄和处理图片的实现
2019/08/06 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
2020/04/20 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
基于Python的身份证验证识别和数据处理详解
2020/11/14 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
Python中使用Selenium环境安装的方法步骤
2021/02/22 Python
谷歌浏览器小字体处理方案即12px以下字体
2013/12/17 HTML / CSS
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
最新教师自我评价分享
2013/11/12 职场文书
房地产项目策划书
2014/02/05 职场文书
学校安全生产月活动总结
2014/07/05 职场文书
七一建党日演讲稿
2014/09/05 职场文书
2015年幼儿园教研活动总结
2015/03/25 职场文书
葬礼主持词
2015/07/02 职场文书
Python中json.dumps()函数的使用解析
2021/05/17 Python