当前位置:编程学习 > JS >>

struts2数据同步原理

用过struts2的人都知道,struts2有个很大的特点就是可以不再面向Servlet API编程,从Action的方法签名就可以看出,其execut方法不接收任何参数,返回值也仅仅是String.从而实现与Servlet API的解耦,语法层面上脱离了Web容器。
当要在Web层即控制器向视图层传递数据时,传统做法都是存储在HttpServletRequest、HttpServletSession、ServletContext对象中。
   而在struts2中使用其提供的API就可以操作request,session,application这些用于向页面传递数据的对象,这里说的request,session,application是不同于上面所讲的,它们是Map对象,所以才实现与Servlet API的解耦。当然还有parameters对象,还有一个stuts2扩展的attr对象,下面就详细讲解这其中的原理。
 
在讲解之前须要知道ActionContext是如何创建而来的,所以先把这个讲明白:
struts2的核心分发器Dispatcher中有两重载的方法:createContextMap,下面是这两个方法的源码:
[java] 
public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,  
            ActionMapping mapping, ServletContext context) {  
  
        // request map wrapping the http request objects  
        Map requestMap = new RequestMap(request);//将request封装成一个RequestMap对象  
  
        // parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately  
        Map params = new HashMap(request.getParameterMap());//将请求参数放在HashMap中  
  
        // session map wrapping the http session  
        Map session = new SessionMap(request);//将session封装在一个SessionMap中(通过request.getSession可获取session)  
  
        // application map wrapping the ServletContext  
        Map application = new ApplicationMap(context);//把ServeltContext封装在成一个ApplicationMap对象  
  
        Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);  
  
        if (mapping != null) {  
            extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);  
        }  
        return extraContext;  
    }  
 
[java]  
public HashMap<String,Object> createContextMap(Map requestMap,  
                                    Map parameterMap,  
                                    Map sessionMap,  
                                    Map applicationMap,  
                                    HttpServletRequest request,  
                                    HttpServletResponse response,  
                                    ServletContext servletContext) {  
        HashMap<String,Object> extraContext = new HashMap<String,Object>();  
        extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));  
        extraContext.put(ActionContext.SESSION, sessionMap);  
        extraContext.put(ActionContext.APPLICATION, applicationMap);  
  
        Locale locale;  
        if (defaultLocale != null) {  
            locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());  
        } else {  
            locale = request.getLocale();  
        }  
  
        extraContext.put(ActionContext.LOCALE, locale);  
        //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode));  
  
        extraContext.put(StrutsStatics.HTTP_REQUEST, request);  
        extraContext.put(StrutsStatics.HTTP_RESPONSE, response);  
        extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);  
  
        // 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;  
    }  
 
    首先要说明的是createContextMap方法返回的Map中的数据就是要放到ActionContext中的数据。
    第一个createContextMap所做的工作看注释应该都知道了,但有一个细节不知道大家注意到没有,为什么parameters是存放在一个HashMap中,而不是在一个ParametersMap中,当然ParametersMap这个类是不存在的,sturts2开发者没有为请求参数开发一个用于封装请求参数的类,而是直接存放在HashMap中。但是像request,session,application都有对应的封装Map类。这是因为对于请求参数来说在请求到来的时候就已经确定了,不会再变化,而request,session,application这些对象到了Action或者Interceptor中我们会向其添加数据,封装后利于在Action中与Servlet API解耦。
   第一个createContextMap调用了第二个createContextMap方法,把Servlet原生的与封装好的request,session,application都传了进去,第二个createContextMap方法所做的工作也很简单就是把Servlet原生的与封装好的对象都放在了一个HashMap(extraContext)中,然后返回,注意这个大的HashMap中的所有数据都会放到ActionContext中。
   还有一个要先讲的就是在struts2中,所使用的request是struts2经过包装的StrutsRequestWrapper类,继承自javax.servlet.http.HttpServletRequestWrapper,并且覆盖了getAttribute方法,下面是该方法源码:
[java]  
public Object getAttribute(String s) {  
        if (s != null && s.startsWith("javax.servlet")) {  
            // don't bother with the standard javax.servlet attributes, we can short-circuit this  
            // see WW-953 and the forums post linked in that issue for more info  
          &n
补充:Web开发 , Jsp ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,