GVKun编程网logo

在验收测试期间如何从Struts 2获取ActionContext?(获取测试结果)

15

本文将带您了解关于在验收测试期间如何从Struts2获取ActionContext?的新内容,同时我们还将为您解释获取测试结果的相关知识,另外,我们还将为您提供关于ActionContext和Serv

本文将带您了解关于在验收测试期间如何从Struts 2获取ActionContext?的新内容,同时我们还将为您解释获取测试结果的相关知识,另外,我们还将为您提供关于ActionContext和ServletActionContext小结、ActionContext 和 ServletActionContext 小结、ActionContext与ServletActionContext的区别及获取request、session等对象、ActionContext和ServletActionContext的实用信息。

本文目录一览:

在验收测试期间如何从Struts 2获取ActionContext?(获取测试结果)

在验收测试期间如何从Struts 2获取ActionContext?(获取测试结果)

我在以Struts 2和Tomcat作为我的Servlet容器的应用程序上使用cumulage-
jvm编写了接受测试(测试行为)。在代码的某个时刻,我需要从Struts 2
HttpSession(由创建的)中获取用户HttpServletRequest

由于我正在测试并且未运行Tomcat,因此我没有活动的会话,并且得到了NullPointerException

这是我需要调用的代码:

public final static getActiveUser() {    return (User) getSession().getAttribute("ACTIVE_USER");}

和getSession方法:

public final static HttpSession getSession() {    final HttpServletRequest request (HttpServletRequest)ActionContext.                          getContext().get(StrutsStatics.HTTP_REQUEST);    return request.getSession();}

老实说,我对Struts
2不太了解,所以我需要一些帮助。我一直在看这个带有嵌入式tomcat例子的cumulage-
jvm,但我一直在努力理解。

我也一直在看这个Struts 2
Junit教程。可悲的是,它并没有很好地涵盖所有StrutsTestCase功能,并且是最简单的用例(都被认为是一个非常无用的教程)。

因此,如何像用户正在使用应用程序一样运行验收测试?


更新:

感谢Steven Benitez的回答!

我必须做两件事:

  1. 按照建议模拟HttpServletRequest,
  2. 模拟HttpSession以获取我想要的属性。

这是我添加到cumul-jvm测试中的代码:

public class StepDefs {    User user;    HttpServletRequest request;    HttpSession session;    @Before    public void prepareTests() {        // create a user        // mock the session using mockito        session = Mockito.mock(HttpSession.class);        Mockito.when(session.getAttribute("ACTIVE_USER").thenReturn(user);        // mock the HttpServletRequest        request = Mockito.mock(HttpServletRequest);        Mockito.when(request.getSession()).thenReturn(session);        // set the context        Map<String, Object> contextMap = new HashMap<String, Object>();        contextMap.put(StrutsStatics.HTTP_REQUEST, request);        ActionContext.setContext(new ActionContext(contextMap));    }    @After    public void destroyTests() {        user = null;        request = null;        session = null;        ActionContext.setContext(null);    }

}

答案1

小编典典

An
ActionContext是一个按请求的对象,代表在其中执行操作的上下文。静态方法getContext()setContext(ActionContextcontext)受的支持ThreadLocal。在这种情况下,您可以在测试前调用它:

Map<String, Object> contextMap = new HashMap<String, Object>();contextMap.put(StrutsStatics.HTTP_REQUEST, yourMockHttpServletRequest);ActionContext.setContext(new ActionContext(contextMap));

然后使用以下命令清理它:

ActionContext.setContext(null);

本示例仅提供您需要测试的方法。如果您需要根据此处未提供的代码在地图中添加其他条目,请相应地添加它们。

希望能有所帮助。

<Struts>ActionContext和ServletActionContext小结

ActionContext和ServletActionContext小结

1. ActionContext

在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息,甚至需要直接对JavaServlet Http的请求(HttpServletRequest),响应(HttpServletResponse)操作. 我们需要在Action中取得request请求参数"username"的值:

ActionContext context = ActionContext.getContext(); 
Map params = context.getParameters(); 
String username = (String) params.get("username");
ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象. 一般情况, 我们的ActionContext都是通过: ActionContext context = (ActionContext) actionContext.get();来获取的.我们再来看看这里的actionContext对象的创建:

static ThreadLocal actionContext = new ActionContextThreadLocal();

ActionContextThreadLocal是实现ThreadLocal的一个内部类.ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.

通过ActionContext取得HttpSession: Map session = ActionContext.getContext().getSession();

  2. ServletActionContext

ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了我们上面介绍的ActionContext,它提供了直接与Servlet相关对象访问的功能,它可以取得的对象有:

(1)javax.servlet.http.HttpServletRequest : HTTPservlet请求对象

(2)javax.servlet.http.HttpServletResponse : HTTPservlet相应对象

(3)javax.servlet.ServletContext : Servlet上下文信息

(4)javax.servlet.ServletConfig : Servlet配置对象

(5)javax.servlet.jsp.PageContext : Http页面上下文

如何从ServletActionContext里取得Servlet的相关对象:

<1>取得HttpServletRequest对象: HttpServletRequest request = ServletActionContext. getRequest();

<2>取得HttpSession对象: HttpSession session = ServletActionContext. getRequest().getSession();

  3. ServletActionContext和ActionContext联系

ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问Servlet的相关对象.

注意:在使用ActionContext时有一点要注意: 不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null;同样,HttpServletRequest req = ServletActionContext.getRequest()也不要放在构造函数中,也不要直接将req作为类变量给其赋值。至于原因,我想是因为前面讲到的static ThreadLocal actionContext = new ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的,而ServletActionContext继承自ActionContext,所以ServletActionContext也线程安全,线程安全要求每个线程都独立进行,所以req的创建也要求独立进行,所以ServletActionContext.getRequest()这句话不要放在构造函数中,也不要直接放在类中,而应该放在每个具体的方法体中(eg:login()、queryAll()、insert()等),这样才能保证每次产生对象时独立的建立了一个req。

  4. struts2中获得request、response和session

(1)非IoC方式
/**方法一:使用org.apache.struts2.ActionContext类,通过它的静态方法getContext()获取当前Action的上下文对象。**/
ActionContext ctx = ActionContext.getContext();
ctx.put("liuwei", "andy"); //request.setAttribute("liuwei", "andy"); 
Map session = ctx.getSession(); //session
HttpServletRequest request = ctx.get(org.apache.struts2.StrutsStatics.HTTP_REQUEST); 
HttpServletResponse response = ctx.get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);
细心的朋友可以发现这里的session是个Map对象, 在Struts2中底层的session都被封装成了Map类型. 我们可以直接操作这个Map对象进行对session的写入和读取操作, 而不用去直接操作HttpSession对象.
方法二:使用org.apache.struts2.ServletActionContext类
public class UserAction extends ActionSupport { 
     
    //其他代码片段 
     
    private HttpServletRequest req; 
// private HttpServletRequest req = ServletActionContext.getRequest(); 这条语句放在这个位置是错误的,同样把这条语句放在构造方法中也是错误的。
    public String login() { 
        req = ServletActionContext.getRequest(); //req的获得必须在具体的方法中实现 
        user = new User(); 
        user.setUid(uid); 
        user.setPassword(password); 
        if (userDAO.isLogin(user)) { 
            req.getSession().setAttribute("user", user); 
            return SUCCESS; 
        } 
        return LOGIN; 
    } 
    public String queryAll() { 
        req = ServletActionContext.getRequest(); //req的获得必须在具体的方法中实现 
        uList = userDAO.queryAll(); 
        req.getSession().setAttribute("uList", uList); 
        return SUCCESS; 
    } 
     
    //其他代码片段 
}
(2)IoC方式(即使用Struts2 Aware拦截器)
要使用IoC方式,我们首先要告诉IoC容器(Container)想取得某个对象的意愿,通过实现相应的接口做到这点。
public class UserAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {
    private HttpServletRequest request; 
    private HttpServletResponse response;
    public void setServletRequest(HttpServletRequest request) { 
        this.request = request; 
    }
    public void setServletResponse(HttpServletResponse response) { 
        this.response = response; 
    }
    public String execute() { 
        HttpSession session = request.getSession(); 
        return SUCCESS; 
    } 
}


ActionContext 和 ServletActionContext 小结

ActionContext 和 ServletActionContext 小结

http://www.cnblogs.com/tanglin_boy/archive/2010/01/18/1650871.html

ActionContext与ServletActionContext的区别及获取request、session等对象

ActionContext与ServletActionContext的区别及获取request、session等对象

一、ActionContext

 ActionContext是Action执行的上下文,Action的上下文可以看作是一个容器,里面封装了请求(Request)、会话(Session)、Application等,这里面的Request、Session、Application是Map类型的,往里面封装的是键值对,所以这就体现了struts2不与底层servlet Api打交道,那么对很多web的相关对象进行封装,这样可以达到Action与web层解耦。

用ActionContext得到Map类型的Request、Session、Application。

例子:

    获取request

     Map request = ActionContext.getContext().get("request");

    往request里封装数据

    request.put("name", value);

    在前台就可以用request.getAttribute("name");

   

    获取session

    Map session = ActionContext.getContext().getSession();

    将数据封装到session中

    session.put("name", value);

    在前台页面上用sessionScope.getAttribute("name");得到session里面封装的值。

得到session、request有点区别,得到request用的是get("reqeust"),得到session用的是getSession()

 

也可以直接对Java Servlet Http的请求(HttpServletRequest)、响应(HttpServletResponse)操作,和上面的例子有点区别,注意区别

ActionContext ctx = ActionContext.getContext();       
      
  HttpServletRequest request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST);
  HttpServletResponse response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE);

用法就和Servlet中的request、response用法一样

 

二、ServletActionContext

它继承ActionContext,所以ServletActionContext也可以得到HttpServetRequest、HttpServletResponse,,它也提供了直接与Servlet相关对象访问的功能,它可以取得的对象有:

(1)javax.servlet.http.HttpServletRequest : HTTPservlet请求对象

(2)javax.servlet.http.HttpServletResponse : HTTPservlet相应对象

(3)javax.servlet.ServletContext : Servlet上下文信息

(4)javax.servlet.ServletConfig : Servlet配置对象

(5)javax.servlet.jsp.PageContext : Http页面上下文

 

如何获取HttpRequest、HttpResponse

例子

  HttpServletRequest request = ServletActionContext.getRequest();

  HttpServletResponse response = ServletActionContext.getResponse();

然后就可以用request.setAttribute("name", value)方法了。

 

总结:不难看出,两者之间还是存在很多共同功能,那么我们还是根据自己的需求进行选择,能用ActionContext对象满足就尽量使用ActionContext,避免让我们直接去访问Servlet对象。另外,不要在Action还没实例化的时候去通过ActionContext调用方法,因为Action实例在ActionContext实例之前创建,ActionContext中一些值还没有设置,会返回null。

ActionContext和ServletActionContext

ActionContext和ServletActionContext

前面已经了解到ActionContext是Action执行时的上下文,里面存放着Action在执行时需要用到的对象,我们也称之为广义值栈。

       Struts2在每次执行Action之前都会创建新的ActionContext,在同一个线程里ActionContext里面的属性是唯一的,这样Action就可以在多线程中使用。

1:ActionContext的线程安全性

       那么Struts2是如何保证ActionContext的线程安全性呢?

       看看ActionContext对象的代码,示例如下:

public class ActionContext implements Serializable {  
static ThreadLocal actionContext = new ThreadLocal();  
……  
}



ThreadLocal又称为“线程局部变量”,它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

存放在ActionContext里的数据都存放在这个ThreadLocal的属性中,而这个属性只会在对应的当前请求线程中可见,从而保证数据是线程安全的。

2:访问的是Map

回顾前面在使用ActionContext来访问Session中数据的程序,你会发现,其实在程序里面访问的是一个Map,而非HttpSession对象,这是为什么呢?

       原来,Struts2框架将与Web相关的很多对象重新进行了包装,比如将HttpSession对象重新包装成了一个Map对象,里面存放着Session中的数据,提供这个Map给Action使用,而不用Action直接和底层的HttpSession打交道。也正是因为框架的包装,让Action可以完全的和Web层解耦。

       但是要注意一点,ActionContext不能在普通的Java应用程序中使用。

在以前的学习中,介绍了Action和Servlet API是解耦的,因此可以在Java应用程序中调用Action的execute方法来进行测试。但是如果使用了ActionContext来获取session数据,那么就不能这样运行了。因为ActionContext包装的都是Web的数据,在Java应用程序中运行的时候,没有Web的环境和响应的数据,因而会抛出空指针的异常。

访问其它的Web对象的值也是与此类似的,你通过ActionContext去访问的都是包装后的Map。

3:使用SessionAware接口

Struts2还提供另外一种简单的方式,使用SessionAware接口来访问存储于ActionContext中的数据,该接口通过使用IoC/DI来为Action注入Session Map,就可以在程序里面直接使用这个Map来操作数据了。

 (1)在Action中不再需要访问ActionContext了,取而代之,Action实现SessionAware接口,该接口告知Struts2在Action执行之前要设置Session Map,是通过servletConfig 拦截器来实现的,这个拦截器在defaultStack里面就有。示例代码如下:

public class OgnlAction extends ActionSupport implements SessionAware{  
    private Map<String, Object> session;  
    @Resource
    public void setSession(Map<String, Object> session) {  
        this.session = session;  
    }  
      
    public String execute(){  
        session.put("sessionTestKey", "测试SessionAware");  
        return this.SUCCESS;  
    }  
}



在上面的代码中:

  • Action类实现SessionAware接口
  • 这个接口要求Action类实现一个方法setSession(Map<String, Object> session),通过这个方法注入Session的数据
  • 在execute方法中,通过这个私有属性就可以操作会话中的数据,注意一点,这个Map中的值也是与HttpSession联动的。


为了能够在普通的Java应用中运行并测试Action,推荐大家使用SessionAware的方式来访问HttpSession。因为这样一来,在通过main方法运行或测试的时候,可以直接调用setSession方法,传入模拟的会话数据,就不会出现execute方法中抛出空指针的异常了。

       因此,推荐大家使用SessionAware的方式来访问HttpSession。

4:使用其它包装接口

跟SessionAware类似,你可以使用RequestAware来获取包装请求对象的attribute中的值的Map;使用ApplicationAware来获取包装ServletContext对象的attribute中的值的Map;使用ParameterAware来获取包装请求对象的参数中的值的Map,等等,这里只罗列这几个常见和常用的,还有更多的请参见Struts2的API文档。



在实际应用开发中,光是获取数据就够了吗?答案显然是否定的,有些时候,根据功能需要,在Action中必须要能获取到Servlet相关的API,比如要操作Cookie。这个时候,就需要用ServletActionContext了。

1:ServletActionContext概述

这个类直接继承了ActionContext,当然也继承了它父类的很多功能,比如:对OgnlValueStack、Action名字等的访问。更重要的是,它还提供了直接访问Servlet的相关对象的功能,它可以取得的对象有:

  • HttpServletRequest:请求对象
  • HttpServletResponse:响应对象
  • ServletContext:Servlet上下文信息
  • PageContext:Http页面上下文


2:基本使用

       直接使用ServletActionContext的静态方法就可以获取到相应的对象。示例如下:

 

java代码:
HttpServletRequest request = ServletActionContext.getRequest();  
HttpServletResponse response = ServletActionContext.getResponse();  
ServletContext servletContext = ServletActionContext.getServletContext();  
PageContext pageContext = ServletActionContext.getPageContext();  
HttpSession session = ServletActionContext.getRequest().getSession();


这里要注意的是HttpSession对象的获取,是在取得HttpRequest对象过后,通过HttpRequest对象来获取会话对象。当然,取得相应的对象后,就直接使用这些对象的方法来进行开发,这里就不去赘述了。

3:通过IoC/DI的方式来获取相应的Servlet对象

       还可以通过IoC/DI的方式来获取相应的Servlet对象,对应关系是:

  • ServletRequestAware:通过这个接口来获取HttpServletRequest对象
  • ServletResponseAware:通过这个接口来获取HttpServletResponse对象

用ServletRequestAware来示例一下。

(1)修改Action,让其实现ServletRequestAware接口,示例代码如下:

 java代码:

public class OgnlAction extends ActionSupport implements ServletRequestAware{  
    private HttpServletRequest request = null;  
    @Resource
    public void setServletRequest(HttpServletRequest request) {  
        this.request = request;  
    }  
      
    public String execute(){          
        request.setAttribute("request", "Request的属性值");  
        request.getSession().setAttribute("sessionTestKey", "测试SessionAware");  
        return this.SUCCESS;  
    }     
}




ActionContextServletActionContext

根据前面的讲述,你会发现,ActionContext和ServletActionContext有着一些重复的功能,都能够获取到Web对象的数据,但是又有些不同。

       通常情况下,可以这么认为:ActionContext主要负责值的操作;ServletActionContext主要负责获取Servlet对象。

那么在Action中,该如何去抉择呢?建议的原则是:

  • 优先使用ActionContext
  • 只有ActionContext不能满足功能要求的时候,才使用ServletActionContext

总之,要尽量让Action与Web无关,这对于Action的测试和复用都是极其有好处的。

       另外还有一点需要注意:在使用ActionContext时,不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许还没有设置,这时通过ActionContext取得的值也许是null。








今天关于在验收测试期间如何从Struts 2获取ActionContext?获取测试结果的分享就到这里,希望大家有所收获,若想了解更多关于ActionContext和ServletActionContext小结、ActionContext 和 ServletActionContext 小结、ActionContext与ServletActionContext的区别及获取request、session等对象、ActionContext和ServletActionContext等相关知识,可以在本站进行查询。

本文标签: