东东东 陈煜东的博客

标签存档: struts

用junit对struts2 action和spring进行单元测试

对action和spring进行测试,就不用再开tomcat了,此方法就是模拟用户的http请求进行的,但是这个方法不能看页面的工作情况,但对action的测试足够了。

此测试方法参考了http://depressedprogrammer.wordpress.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/ ,此方法在我的代码中不能正常工作,需要改动。

首先需要的jar文件:spring-test-3.05.RELEASE.jar、spring-core-3.1.5RELEASE.jar,文中并没有给出相关依赖jar包。

public class PersonAction extend ActionSupport {

  private int id;

  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String deletePerson() {
    ....
    return SUCCESS;
  }
}
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;
import junit.framework.TestCase;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.views.JspSupportServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.ContextLoader;

import java.util.HashMap;

/**
 * @author Zarar Siddiqi
 */
public abstract class BaseStrutsTestCase extends TestCase {
    private static final String CONFIG_LOCATIONS = "file:WebRoot/WEB-INF/applicationContext.xml";
    private static ApplicationContext applicationContext;
    private Dispatcher dispatcher;
    protected ActionProxy proxy;
    protected static MockServletContext servletContext;
    protected static MockServletConfig servletConfig;
    protected MockHttpServletRequest request;
    protected MockHttpServletResponse response;

    public BaseStrutsTestCase(String name) {
        super(name);
    }

    /**
     * Created action class based on namespace and name
     * @param clazz Class for which to create Action
     * @param namespace Namespace of action
     * @param name Action name
     * @return Action class
     * @throws Exception Catch-all exception
     */
    @SuppressWarnings("unchecked")
    protected <T> T createAction(Class<T> clazz, String namespace, String name)
            throws Exception {

        // create a proxy class which is just a wrapper around the action call.
        // The proxy is created by checking the namespace and name against the
        // struts.xml configuration
        proxy = dispatcher.getContainer().getInstance(ActionProxyFactory.class).
                createActionProxy(
                namespace, name, null, true, false);

        // by default, don't pass in any request parameters
        proxy.getInvocation().getInvocationContext().
                setParameters(new HashMap());

        // do not execute the result after executing the action
        proxy.setExecuteResult(true);

        // set the actions context to the one which the proxy is using
        ServletActionContext.setContext(
                proxy.getInvocation().getInvocationContext());
        request = new MockHttpServletRequest();
        response = new MockHttpServletResponse();
        ServletActionContext.setRequest(request);
        ServletActionContext.setResponse(response);
        ServletActionContext.setServletContext(servletContext);
        return (T) proxy.getAction();
    }

    protected void setUp() throws Exception {
        if( applicationContext == null ) {
            // this is the first time so initialize Spring context
            servletContext = new MockServletContext();
            servletContext.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM,
                    CONFIG_LOCATIONS);
            applicationContext = (new ContextLoader()).initWebApplicationContext(servletContext);

            // Struts JSP support servlet (for Freemarker)
            new JspSupportServlet().init(new MockServletConfig(servletContext));
        }
        // Dispatcher is the guy that actually handles all requests.  Pass in
        // an empty. Map as the parameters but if you want to change stuff like
        // what config files to read, you need to specify them here.  Here's how to
        // scan packages for actions (thanks to Hardy Ferentschik - Comment 66)
        // (see Dispatcher's source code)
        HashMap params = new HashMap();
        params.put("actionPackages", "com.test.action");
        dispatcher = new Dispatcher(servletContext, params);
        dispatcher.init();
        Dispatcher.setInstance(dispatcher);
    }
}

文中第20行在我的myeclipse不能工作,本来按原文的方法是抛出FileNotFound异常,采用改为file:WebRoot/WEB-INF/applicationContext.xml来解决的。其中第87行需要改成自己的包名。

public class PersonActionTest extends BaseStrutsTestCase {

 /**
  * Invoke all interceptors and specify value of the action
  * class' domain objects directly.
  * @throws Exception Exception
  */
 public void testInterceptorsBySettingDomainObjects()
         throws Exception {
  PersonAction action = createAction(PersonAction.class,
                "/site", "deletePerson");
  action.setId(123);
  String result = proxy.execute();
  assertEquals(result, "success");
 }

 /**
  * Invoke all interceptors and specify value of action class'
  * domain objects through request parameters.
  * @throws Exception Exception
  */
 public void testInterceptorsBySettingRequestParameters()
                     throws Exception {
  createAction(PersonAction.class, "/site", "deletePerson");
  request.addParameter("id", "123");
  String result = proxy.execute();
  assertEquals(result, "success");
 }

 /**
  * Skip interceptors and specify value of action class'
  * domain objects by setting them directly.
  * @throws Exception Exception
  */
 public void testActionAndSkipInterceptors() throws Exception {
  PersonAction action = createAction(PersonAction.class,
                  "/site", "deletePerson");
  action.setId(123);
  String result = action.deletePerson();
  assertEquals(result, "success");
 }
}

自己编写testcase继承该类即可。按照这个格式编写测试用例。

另外的junit方法,查看http://developer.51cto.com/art/201108/282751.htm

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 用junit对struts2 action和spring进行单元测试 – https://www.chenyudong.com/archives/unit-testing-struts-2-actions-and-spring-using-junit.html

分类: 网站建设

获取struts2 include标签param参数

struts 2的标签中,有个<s:include>标签,这个标签能将其他页面给包含到本页面。使用这个语法,能将网页给模块化了。不用写一个长长的页面,将相同的部分给抽取出来,从而复用代码。

同时,我们也可以向要include进来的页面传入参数。在被include的页面中,我们可以读取。

向include传入参数

<s:include value="myJsp.jsp" />
<s:include value="myJsp.jsp">
   <s:param name="param1" value="value2" />
   <s:param name="param2" value="value2" />
</s:include>
<s:include value="myJsp.jsp">
   <s:param name="param1">value1</s:param>
   <s:param name="param2">value2</s:param>
</s:include>

取参数方法一:${param.ParamName}官方的唯一方法

在被include页中取出参数,在myJsp.jsp页面中,获得参数的方法就是${param.ParamName}。

<div>通过这样取出参数值${param.param1}</div>

对了,要获得参数必须使用param这个对象。根据官方的struts include document说明,只能通过${param.param1}这样取出,其他方法不能直接取出来,<s:property>标签不能取出参数。

注意:不要在<s:property>标签的属性里使用${}标记,${}能够在html代码中直接显示。如果需要,请查阅Expression Language (EL)

取参数方法二:利用request对象来传递

include传参数还是一样的方法。但是在取参数,使用里一些小技巧。

<% pageContext.setAttribute("myparam" , request.getParameter("param1")); %>           
<s:property value="#attr.myparam"/>

通过pageContext对象来设置参数,或者你也可以使用request对象来实现参数的设置。有点投机了,不过此方法只能取字符串?为什么我不能获得其他值呢?

取参数方法三:不用include传入参数,在外头定义约定变量

<s:set name="param1" value="#request.user" />
<s:include value="myJsp.jsp" />

此方法有点投机取巧了。没有经过include标签传入参数,但在外头定义一个变量,在myJsp.jsp页取得共同约定的变量也不错。这样,在myJsp.jsp页中可以使用struts标签,和正常的情况一样使用,用起来很方便。个人喜欢使用这个方法。

取参数方法四:自己设置valueStack

参考文章来源:http://blog.csdn.net/james_wu_shanghai/article/details/4034739

在myJsp.jsp页面中自己忘valueStack添加自己的值。

<%@page import="com.opensymphony.xwork2.ognl.OgnlValueStack"%>
<%
 ((OgnlValueStack) request.getAttribute("struts.valueStack")).set(
   "operation", request.getParameter("operation"));
%>

<s:property value="operation"/>

此方法本人也用过,能正常工作,但是在其他页面出现问题了,详情请查看struts里不能获得request的参数。立刻将此方法撤下了。

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: 获取struts2 include标签param参数 – https://www.chenyudong.com/archives/access-struts2-include-tag-parameter-in-another-jsp-page.html

分类: 网站建设

struts action json 示例

想使用Ajax来请求数据,但是后台都是使用struts和一堆的Action写的,这个要如何写呢?

大家应该都知道JSON和Ajax是什么吧?如果还不知道也不会继续阅读下去。

采用Action来返回JSON数据

第一步,导入struts2-json-plugin.jar包。如果没有该jar包,那么到http://struts.apache.org/download.cgi下载一个struts包,里面包含该jar包。

第二步:编写一个Action类

package com.chenyudong.action;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class AjaxAction extends ActionSupport {
    private static final long serialVersionUID = -5279892367628798557L;
    
    Map<String,Object> map = new HashMap<String,Object>();
    List<Object> list = new LinkedList<Object>();

    public Map<String, Object> getMap() {return map;}
    public void setMap(Map<String, Object> map) {this.map = map;}
    public List<Object> getList() {return list;}
    public void setList(List<Object> list) {this.list = list;}

    public String test(){
        map.put("username", "abc"); 
        return SUCCESS;
    }
}

第三步:配置struts.xml文件

<package name="struts2" extends="struts-default,json-default">
    <action name="ajax" class="com.chenyudong.action.AjaxAction" method="test">
        <result type="json"></result>
    </action>
</package>

第四步:访问网页得到结果

{"list":[],"map":{"username":"abc"}}

该方法需要注意的地方,在AjaxAction类中,有成员变量map和list,在方法中,我没有使用list成员变量,由于设置get和set方法,我的输出结果中,有list值。也就是使用该方法,会出现成员变量中的所有有get的成员都会输出。如果想要不想显示无关的list或者map,使用注解@JSON(serialize=false)

声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客

本文链接地址: struts action json 示例 – https://www.chenyudong.com/archives/struts-action-json-example.html

分类: JavaEE

Copyright © 2017 东东东 陈煜东的博客 粤ICP备13059639号-1

SITEMAP回到顶部 ↑