通过ActionContext类访问Servlet对象

 ActionContext类位于com.opensymphony.xwork2中,提供一系列相关方法用于访问保存在ServletContext、HttpSession、HttpServletRequest中的信息,并且存储在Map中。需要注意的是,该类并没有提供获取ServletContext、HttpSession、HttpServletRequest等对象的方法。ActionContext类的常用方法见下表:

方法
解释
public Map getParameters()
从请求对象(HttpServletRequest)中获取请求参数
public Map getApplication()
获取ServletContext中保存的Attribute
public Map getSession()
获取HttpSession中保存的Attribute
       那么,这些信息是在什么时候保存进去的呢?从源代码中分析,所有秘密都隐藏在 org.apache.struts2.dispatcher. Dispatcher类中,该类中定义了一个createContextMap()方法,代码如下:
代码清单29 :Dispatcher. createContextMap() 方法
    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中所有的Attribute
        // parameters map wrapping the http paraneters.
        Map params = null;
        if (mapping != null) {
            params = mapping.getParams();
        }
        Map requestParams = new HashMap(request.getParameterMap());//存放request中所有的Parameter
        if (params != null) {
            params.putAll(requestParams);
        } else {
            params = requestParams;
        }
        // session map wrapping the http session
        Map session = new SessionMap(request);//存放Session中所有的Attribute
        // application map wrapping the ServletContext
        Map application = new ApplicationMap(context);//存放ServletContext所有的Attribute
        Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);
        extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
        return extraContext;
    }
      
       接下来又调用了另一个重载的createContextMap()方法,该方法不仅保存Attribute,而且保存request,response和servletContext对象,请看源代码:
代码清单 30 :重载的Dispatcher. createContextMap() 方法
    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类型的数据最终又被保存在了另一个Map中,ActionContext就是从这个Map中获取数据的。
    在ActionContext类中定义了一个静态方法public static ActionContext getContext()用于获取自己的一个实例,不能new此类的对象。
    下面的示例演示了ActionContext类的基本用法,即从请求参数中读取id和name的值,并且将值保存到Session中,然后跳转到session.jsp页面将id和name的值显示出来。
    先定义ServletAction类,代码如下:
代码清单 31 ServletAction.java
package com.lizanhong.chapter3;
import java.util.Map;
import java.util.Set;
import com.opensymphony.xwork2.ActionContext;
public class ServletAction {
    public String execute(){
       ActionContext ac = ActionContext. getContext();
       Map paramMap = ac.getParameters();
       String[] ids = (String[]) paramMap.get("id");
       String[] names = (String[]) paramMap.get("name");
      
       Map sessionMap = ac.getSession();
       sessionMap.put("id", ids[0]);
       sessionMap.put("name", names[0]);
       return "toSession";
    }
}
注:通过getParameters()方法获取到的请求参数类型都是String[],必须根据实际情况取值。如果只有一个值的话,取出数组中第0个元素即可。
   
    以下是ServletAction在struts.xml中的配置。
代码清单 33 :在 struts.xml 中的配置
<action name="servletAction" class="com.lizanhong.chapter3.ServletAction">
    <result name="toSession">/session.jsp</result>
</action>
   
在session.jsp页面中,使用表达式语言(EL)显示保存在Session中的id和name值。
代码清单 33:session.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>My JSP 'session.jsp' starting page</title>
</head>
<body>
    ${id }<br>
    ${name }
</body>
</html>
    请求参数通过表单页面idname.jsp提供。
代码清单 34 idname.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>My JSP 'idname.jsp' starting page</title>
</head>
<body>
    <form action=" servletAction.action" method="post">
        ID:<input name="id"><br>
        Name:<input name="name"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
    通过http://localhost:8081/Struts2Demo/idname.jsp地址访问即可,图24是表单输入效果,图25是表单提交后将请求发送给Action,最后显示在session.jsp中的效果:
    (图24)
    (图25)
    ActionContext类是xwork提供的,struts2定义了一个新类org.apache.struts2. ServletActionContext,该类继承自ActionContext:
代码清单 35 ServletActionContext.java 的定义
public class ServletActionContext extends ActionContext implements StrutsStatics {
}
    ServletActionContext类和ActionContext相比扩展了更多的方法,主要是一些静态方法,该类的源代码如下:
代码清单 36 ServletActionContext.java 的完整定义
public class ServletActionContext extends ActionContext implements StrutsStatics {
    private static final long serialVersionUID = -666854718275106687L;
    public static final String STRUTS_VALUESTACK_KEY = "struts.valueStack";
    public static final String ACTION_MAPPING = "struts.actionMapping";
    @SuppressWarnings("unused")
    private ServletActionContext(Map context) {
        super(context);
    }
    public static ActionContext getActionContext(HttpServletRequest req) {
        ValueStack vs = getValueStack(req);
        if (vs != null) {
            return new ActionContext(vs.getContext());
        } else {
            return null;
        }
    }
    public static ValueStack getValueStack(HttpServletRequest req) {
        return (ValueStack) req.getAttribute( STRUTS_VALUESTACK_KEY);
    }
    public static ActionMapping getActionMapping() {
        return (ActionMapping) ActionContext.getContext().get( ACTION_MAPPING);
    }
    public static PageContext getPageContext() {
        return (PageContext) ActionContext.getContext().get(PAGE_CONTEXT);
    }
    public static void setRequest(HttpServletRequest request) {
        ActionContext.getContext().put(HTTP_REQUEST, request);
    }
    public static HttpServletRequest getRequest() {
        return (HttpServletRequest) ActionContext.getContext().get(HTTP_REQUEST);
    }
    public static void setResponse(HttpServletResponse response) {
        ActionContext.getContext().put(HTTP_RESPONSE, response);
    }
    public static HttpServletResponse getResponse() {
         return (HttpServletResponse) ActionContext.getContext().get(HTTP_RESPONSE);
    }
    public static ServletContext getServletContext() {
        return (ServletContext) ActionContext.getContext().get(SERVLET_CONTEXT);
    }
    public static void setServletContext(ServletContext servletContext) {
        ActionContext.getContext().put(SERVLET_CONTEXT, servletContext);
    }
}
    注意粗体部分,getPageContext()方法返回PageContext的引用,getRequest()方法返回HttpServletRequest的引用,getResponse()方法返回HttpServletResponse的引用,getServletContext()方法返回ServletContext的引用。我们将代码清单31修改成代码清单37所示:
代码清单 37 ServletAction.java 的修改版
public class ServletAction {
    public String execute(){
       String id = ServletActionContext. getRequest().getParameter("id");
       String name = ServletActionContext. getRequest().getParameter("name");
      
       Map sessionMap = ServletActionContext. getContext().getSession();
       sessionMap.put("id", id);
       sessionMap.put("name", name);
      
       System. out.println("id=" + sessionMap.get("id"));
       System. out.println("name=" + sessionMap.get("name"));
       return "toSession";
    }
}

3.3.2 通过IOC访问Servlet对象

    在Struts2中,可以通过IOC(依赖注入)将Servlet对象注入到Action中,这一切都是由一组接口决定的,这一组接口有一个共同点,名称都由Aware结尾。以下是这些接口的解释说明:

接口定义
作用
public interface ApplicationAware {
    public void setApplication(Map application);
}
以Map类型向Action注入保存在ServletContext中的Attribute集合。
public interface SessionAware {
    public void setSession(Map session);
}
以Map类型向Action注入保存在HttpSession中的Attribute集合。
public interface ServletResponseAware {
    public void setServletResponse(HttpServletResponse response);
}
向Action中注入HttpServletResponse对象
public interface ServletRequestAware {
    public void setServletRequest(HttpServletRequest request);
}
向Action中注入HttpServletRequest对象
public interface RequestAware {
    public void setRequest(Map request);
}
以Map类型向Action注入保存在HttpServletRequest中的Attribute集合。
public interface CookiesAware {
    void setCookiesMap(Map cookies);
}
以Map类型向Action注入Cookie中的数据集合。
public interface ParameterAware {
    public void setParameters(Map parameters);
}
向Action中注入请求参数集合。
    为了将相关Servlet对象注入到Action中,只要让Action实现这些接口就可以了,Struts2会自动将数据及对象注入Action。代码清单38是对代码清单37的再次修改版:
代码清单 38 ServletAction2.java
public class ServletAction2 implements CookiesAware,ParameterAware, RequestAware, SessionAware, ServletRequestAware, ServletResponseAware, ApplicationAware {
    private Map sessionMap;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private Map applicationMap; //只是定义,代码中没有使用,起演示说明作用
    private Map cookieMap; //只是定义,代码中没有使用,起演示说明作用
    private Map requestMap; //只是定义,代码中没有使用,起演示说明作用
    private Map parameterMap; //只是定义,代码中没有使用,起演示说明作用
   
    public void setSession(Map session) {
       this.sessionMap = session;
    }
    public void setServletRequest(HttpServletRequest request) {
       this.request = request;
    }
    public void setServletResponse(HttpServletResponse response) {
       this.response = response;
    }
    public void setApplication(Map application) {
       this.applicationMap = application;
    }
   
    public void setCookiesMap(Map cookies) {
       this.cookieMap = cookies;
    }
    public void setParameters(Map parameters) {
       this.parameterMap = parameters;
    }
    public void setRequest(Map request) {
       this.requestMap = request;
    }
    public String execute(){
       String id = this.request.getParameter("id");
       String name = this.request.getParameter("name");
      
       sessionMap.put("id", id);
       sessionMap.put("name", name);
       return "toSession";
    }
}
    该Action的配置如下:
代码清单 40 ServletAction2 的配置
<action name="servletAction2" class="com.lizanhong.chapter3.ServletAction2">
       <result name="toSession">/session.jsp</result>
</action>

    可以看出,不需要做其他额外的配置。

http://hi.baidu.com/%C6%C6%D4%C6%B5%B6/blog/item/93be0c2240178cf6d6cae26f.html

你可能感兴趣的:(html,jsp,servlet,struts,IOC)