详解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 相关文章推荐
formvalidator验证插件中有关ajax验证问题
Jan 04 Javascript
自定义jQuery选项卡插件实例
Mar 27 Javascript
Flexigrid在IE下不显示数据的处理的解决方法
Oct 24 Javascript
js调试系列 控制台命令行API使用方法
Jun 18 Javascript
nw.js实现类似微信的聊天软件
Mar 16 Javascript
微信小程序 Video API实例详解
Oct 02 Javascript
Vue中父组件向子组件通信的方法
Jul 11 Javascript
深入浅析var,let,const的异同点
Aug 07 Javascript
ng-repeat指令在迭代对象时的去重方法
Oct 02 Javascript
Vue监听页面刷新和关闭功能
Jun 20 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
Sep 20 Javascript
vue项目中在可编辑div光标位置插入内容的实现代码
Jan 07 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+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
PHP实现Socket服务器的代码
2008/04/03 PHP
详解WordPress中给链接添加查询字符串的方法
2015/12/18 PHP
PHP抽象类与接口的区别详解
2019/03/21 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
javascript html5实现表单验证
2016/03/01 Javascript
个人网站留言页面(前端jQuery编写、后台php读写MySQL)
2016/05/03 Javascript
jQuery插件简单学习实例教程
2016/07/01 Javascript
JS简单实现禁止访问某个页面的方法
2016/09/13 Javascript
深究AngularJS如何获取input的焦点(自定义指令)
2017/06/12 Javascript
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
在vue项目中引用Antv G2,以饼图为例讲解
2020/10/28 Javascript
详解Python当中的字符串和编码
2015/04/25 Python
python3 实现的人人影视网站自动签到
2016/06/19 Python
python实现聊天小程序
2018/03/13 Python
pip命令无法使用的解决方法
2018/06/12 Python
一看就懂得Python的math模块
2018/10/21 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
简单易懂Pytorch实战实例VGG深度网络
2019/08/27 Python
python3.7 利用函数os pandas利用excel对文件名进行归类
2019/09/29 Python
Windows下Anaconda和PyCharm的安装与使用详解
2020/04/23 Python
如何基于Python按行合并两个txt
2020/11/03 Python
美国知名户外用品畅销中心:Sierra Trading Post
2016/07/19 全球购物
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
公司培训欢迎词
2014/01/10 职场文书
运动会广播稿60字
2014/01/15 职场文书
幼儿园教师国培感言
2014/02/02 职场文书
《珍珠泉》教学反思
2014/02/20 职场文书
求职信结尾怎么写
2014/05/26 职场文书
12.4法制宣传日活动总结
2014/08/26 职场文书
领导班子专题民主生活会情况想汇报
2014/09/30 职场文书
诉讼授权委托书
2014/10/15 职场文书
上市公司董事长岗位职责
2015/04/16 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery