Webwork源码分析(转)

以前做项目都是简单的jsp+bean,特没技术含量,终于有机会,自己有个机会决定选择框架,看了不少文章,最后决定用webwork+spring+hibernate来开发。看过了一些文章对这些有了大概的了解。计划五一前,把三个框架深入的研究一下。今天就从webwork开始把。曾经看过夏昕的webwork开发指南,大概流程明白了,具体细节还是不明白,所以下载下源码来看看。

 

我先大致说说我现在对webwork的理解吧。你们一看就知道了,我是初学者,如果有哪位朋友看到这篇文章,觉得里面有我理解不对的地方,希望给我告诉我一声哦。

webwork1我就不说了,我用的是webwork2,他是采用的webwork2+xwork1这样的框架,新框架与Servlet API 分离出来,这给我们的测试带来的极大地方便(这是不选struts的一个原因)。webwork负责把http请求分离出来,使得请求完全脱离Servlet,然后把请求封装到一个Map中,这样传入xwork中的不是Servlet请求,而是一个Map数据结构,xwork就负责根据这个Map数据填充好我们的VO对象,当然它使用的是拦截器的方式来实现的。然后被激活的Action就可以使用VO来进行相应的工作了。我们就顺着这个流程来逐步分析webwork+xwork的实现机制吧。那首先我们就想到的是webwork是如何把http请求封装成Map数据结构的呢?

在我们看了webwork的example,我们看到webwork所有服务都是以.action作为结尾的,但是http不没有以action结尾的服务资源,我们必须在web.xml里做如下的配置:

<servlet>

<servlet-name>webwork</servlet-name>

<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>

<servlet>

<servlet-mapping>

<servlet-name>webwork</servlet-name>

<url-pattern>*.action</url-pattern>

<servlet-mapping>

通过这样的配置以后,应用程序Server就是知道凡是以action结尾的服务请求,都由ServletDipatcher接管。

因此,我就从ServletDispatcher源码开始分析

首先,让我们看看ServletDispatcher.java文件开头的一段说明,这会给你一个对ServletDispatcher工作流程的大概了解。

在webwork中Dispatcher扮演着MVC中的控制器的角色。当请求发送到servlet之后,webwork会做哪些工作呢?

首先,action的名字会从servlet的路径中解析出来(i.e,/foo/bar/MyAction.action--->myAction)

然后,由request,response,parameters,session 和application属性组成的上下文将被创建。

接着,使用action的名字,路径以及上下文实例化ActionProxy,然后执行ActionProxy,最后Action的输出将返回给请求对象。

Servlet使用webwork属性初始化自己,下面这些属性将用于servlet的初始化:

webwork.configuration.xml.reload==true,则每一请求都会重新载入xml配置文件。这个一般用于开发阶段。

webwork.mutipart.saveDir:这个路径被用来保存临时的上传文件。缺省值是应用服务器的临时路径。

webwork.mutipart.maxSize:设置允许多路请求的最大值。

根据说明,大致是这样的。当请求发送到Servlet后,首先要调用ServletDispatcher的init来初始化Servlet,然后调用Service方法,

这个方法主要是得到Action对应的上下文,然后调用serviceAction来执行Action。在serviceAction方法中首先调用createContextMap来

创建Action的上下文环境。我们来仔细分析一下:看源码我们发现,实际上createContextMap就是把http请求的数据全部封装到一个HashMap里面去。

    public static HashMap createContextMap(Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap, HttpServletRequest request, HttpServletResponse response, ServletConfig servletConfig) {


        HashMap extraContext = new HashMap();
        extraContext.put(ActionContext.PARAMETERS, parameterMap);
        extraContext.put(ActionContext.SESSION, sessionMap);
        extraContext.put(ActionContext.APPLICATION, applicationMap);
        extraContext.put(ActionContext.LOCALE, (locale == null) ? request.getLocale() : locale);

        extraContext.put(HTTP_REQUEST, request);
        extraContext.put(HTTP_RESPONSE, response);
        extraContext.put(SERVLET_CONFIG, servletConfig);
        extraContext.put(ComponentInterceptor.COMPONENT_MANAGER, request.getAttribute(ComponentManager.COMPONENT_MANAGER_KEY));

        // helpers to get access to request/session/application scope
        extraContext.put("request", requestMap);
        extraContext.put("session", sessionMap);
        extraContext.put("application", applicationMap);
        extraContext.put("parameters", parameterMap);

        AttributeMap attrMap = new AttributeMap(extraContext);
        extraContext.put("attr", attrMap);

        return extraContext;
    }
整个ServletDispatcher的核心就是serviceAction,然后来看看这个方法:

    public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) {

        //创建了Action的上下文环境
        HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());
        extraContext.put(SERVLET_DISPATCHER, this);

        // 如果存在值栈,就拷贝一个副本,传给新的action使用,否则就创建一个新的值栈。

        OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
        if (stack != null) {
            extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack));
        }

       实际这以下的工作都交给xwork来处理了。
        try {

           //实例化ActionProxy,然后执行Action.
            ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
            request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
            proxy.execute();
            // If there was a previous value stack then set it back onto the request
            if (stack != null){
                request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack);
            }
        } catch (ConfigurationException e) {
            log.error("Could not find action", e);
            sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
        } catch (Exception e) {
            log.error("Could not execute action", e);
            sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值