struts spring integration and test using junit4

1 篇文章 0 订阅
1 篇文章 0 订阅

1、integration

创建java dynamic web project

加入的jar有commons-fileupload-1.2,commons-io-2.2,commons-lang3-3.1,commons-logging-1.1.3,freemarker-2.3.19,hamcrest-core-1.3,javassist-3.11.0.GA,junit-4.12,ognl-3.0.6,spring-***-3.2.8.RELEASE,struts2-core-2.3.15,struts-junit-plugin-2.3.28,struts2-spring-plugin-2.3.15,xwork-core-2.3.15.1

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
<display-name>ssh</display-name>
    <!-- 配置spring监听器 --> 
    <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>   
    <listener>    
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
    </listener>  
    <servlet>
    <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>  
<filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>

    </filter> 

    <!--.do,.action,.jsp文件走struts filter-->

    <filter-mapping>  
        <filter-name>struts2</filter-name>  
        <url-pattern>*.do</url-pattern>  
    </filter-mapping>  
    <filter-mapping>  
        <filter-name>struts2</filter-name>  
        <url-pattern>*.action</url-pattern>  
    </filter-mapping>  
    <filter-mapping>  
        <filter-name>struts2</filter-name>  
        <url-pattern>*.jsp</url-pattern>  
    </filter-mapping>  
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd">  
    <mvc:annotation-driven />                      
    <context:component-scan base-package="com.xik.test.controller" > 
        
    </context:component-scan> 
    <!-- 需要要配置action对应的bean,此步有struts-spring-plugin解决 -->
    <!-- <bean id="hello" class="com.xik.test.action.HelloAction"></bean>   --> 
</beans> 

struts.xml ,该文件放到src下,编译后在classed下,也就是常说的classpath

<?xml version="1.0" encoding="UTF-8" ?>  
  <!DOCTYPE struts PUBLIC  
      "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
      "http://struts.apache.org/dtds/struts-2.3.dtd">  
  <struts> 

     <!--关联spring-->
     <constant name="struts.objectFactory" value="spring"></constant>  

     <!--struts 对应的后缀,和xml中的对应,xml中不使用/*,否则无法使用--> 
     <constant name="struts.action.extension" value="do,action"/>
     <!-- struts的action配置文件 -->  
       
     <!-- 所有的action都应该放在对应的package下 -->  
     <package name="default" extends="struts-default">  
        <action name="hello" class="com.test.action.HelloAction">  
            <!-- 定义逻辑视图和物理资源之间的映射 -->  
            <result name="success">/success.jsp</result>  
            <result name="error">/error.jsp</result>  
        </action>  
     </package>  
  </struts> 

index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>


<%@taglib prefix="s" uri="/struts-tags" %>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>
<head>
<base href="<%=basePath%>">  
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<s:form action="/hello">  
<s:submit key="hello" value="提交"></s:submit>  
</s:form>  
</body>
</html>


success.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Success</title>
</head>
<body>
Success!
</body>
</html>

error.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Error</title>
</head>
<body>
Error!
</body>
</html

@Controller
public class SpringController {


@RequestMapping(value="/hispring")
@ResponseBody
public String hello(HttpServletRequest request){
Object session = request.getSession().getAttribute("sessionName");
String header = request.getHeader("headerName");
String param = request.getParameter("param");
return "Hi Spring" + session + header+param;
}

@RequestMapping(value="/spring/hi")
@ResponseBody
public String hi(){
return "Hello Spring";
}
}

public class HelloAction extends ActionSupport{
/**
 * 
 */
private static final long serialVersionUID = 1L;
public String execute()throws Exception{
    return SUCCESS;
}


}

2、测试spring的controller

@Transactional

@TransactionConfiguration(transactionManager = "transactionManagerForManagement", defaultRollback = false)
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = {"classpath*:applicationContext.xml"})
//@WebAppConfiguration(value = "/WebContent/")
//需要写绝对路径,使用上面的配置会报No mapping found for HTTP request with URI [/hispring] in DispatcherServlet with name ''
//但使用上面的配置test1是可以的
@ContextConfiguration(locations = {"file:E:/projects/mar/workspace/ssh/WebContent/WEB-INF/applicationContext.xml"})
@WebAppConfiguration(value = "file:E:/projects/mar/workspace/ssh/WebContent/")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HelloSpringTest {
    MockMvc mock;
    @Autowired
    private WebApplicationContext wac;
    
    @Before
    public void setUp() throws Exception{
    try{
    mock = MockMvcBuilders.webAppContextSetup(wac).build();
      
    }catch(Exception ex){
    ex.printStackTrace();
    }
    }
    
    @Test
    public void test0() throws Exception{
     
    ResultActions ra = mock.perform(MockMvcRequestBuilders.get("/hispring")
    .sessionAttr("sessionName", " and junit")//设置session值
    .header("headerName", " and User agent")//设置http请求的header值
    .param("param", " and param")//设置http请求的参数
    );
    ra.andExpect(content().string("Hi Spring and junit and User agent and param"));
    MvcResult mr = ra.andReturn();
    String res = mr.getResponse().getContentAsString();
    System.out.println("----------------------------------");
    System.out.println(res);
    }
    @Test
    public void test1() throws Exception{
    SpringController sc = new SpringController();
         mock = MockMvcBuilders.standaloneSetup(sc).build();
    ResultActions ra = mock.perform(MockMvcRequestBuilders.get("/spring/hi"));
    MvcResult mr = ra.andReturn();
    String res = mr.getResponse().getContentAsString();
    System.out.println("----------------------------------");
    System.out.println(res);
    }

}

几点说明

defaultRollback = true时,数据库操作会回滚
FixMethodOrder(MethodSorters.NAME_ASCENDING) 排序方法
    默认(MethodSorters.DEFAULT),按方法名(MethodSorters.NAME_ASCENDING)和JVM(MethodSorters.JVM)
    MethodSorters.DEFAULT hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定 
    按JVM返回的方法名的顺序执行,不可预测顺序
ContextConfiguration(locations 配置文件,目前看需要写绝对路径,也可通过修改org.springframework.test.context.ContextConfigurationAttributes中的resolveLocations来个性化配置

private static String[] resolveLocations(Class<?> declaringClass, ContextConfiguration contextConfiguration) {
Assert.notNull(declaringClass, "declaringClass must not be null");
String path = System.getProperty("java.class.path").split(";")[1];
path = path.substring(0,path.lastIndexOf("WEB-INF"));//个性处理
String[] locations = contextConfiguration.locations();
String[] valueLocations = contextConfiguration.value();


if (!ObjectUtils.isEmpty(valueLocations) && !ObjectUtils.isEmpty(locations)) {
String msg = String.format("Test class [%s] has been configured with @ContextConfiguration's 'value' %s "
+ "and 'locations' %s attributes. Only one declaration of resource "
+ "locations is permitted per @ContextConfiguration annotation.", declaringClass.getName(),
ObjectUtils.nullSafeToString(valueLocations), ObjectUtils.nullSafeToString(locations));
logger.error(msg);
throw new IllegalStateException(msg);
}
else if (!ObjectUtils.isEmpty(valueLocations)) {
locations = valueLocations;
}

        //个性处理
        for(int i=0;i<locations.length;i++){
        if(locations[i].startsWith("/WEB-INF")){
        locations[i] = "file:"+path+locations[i];
        }
        }
return locations;
}

@WebAppConfiguration(value = "/WebContent/")中的属性通过修改org.springframework.test.context.ContextLoaderUtils的buildWebMergedContextConfiguration来处理

private static MergedContextConfiguration buildWebMergedContextConfiguration

...

if (webAppConfigClass != null && testClass.isAnnotationPresent(webAppConfigClass)) {
String path = System.getProperty("java.class.path").split(";")[1];
path = path.substring(0,path.lastIndexOf("WEB-INF"));
Annotation annotation = testClass.getAnnotation(webAppConfigClass);
String resourceBasePath = (String) AnnotationUtils.getValue(annotation);
if("/".equals(resourceBasePath)){
resourceBasePath = path;
}


....

3、测试struts action

public class HelloTest extends StrutsSpringTestCase{
    private ActionProxy proxy;  
  
    protected String[] getContextLocations() {  
        return new String[]{"classpath*:applicationContext.xml"};  
    }  
  
    private void init(){  
        proxy=getActionProxy("/hello.do");  
        HelloAction action  =(HelloAction)proxy.getAction();
        System.out.println(action);
    }  
    
    public void testAdd() throws Exception{  
        init();  
        String ret =  proxy.execute();  
        System.out.println(ret);
    } 
    
    public void testNothing(){
    System.out.println("do nothing");
    }
    
}

如果测试的struts.xml中包含include,最好是在同一级路径下,否则会找不到action

4、@TestExecutionListeners(value={com.test.LicenseListener.class,DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})

LicenseListener 可以在di前做一些需要的事情,如这里的license处理

public class LicenseListener implements TestExecutionListener{
public void afterTestClass(TestContext arg0) throws Exception {}
public void afterTestMethod(TestContext arg0) throws Exception {}
public void beforeTestClass(TestContext arg0) throws Exception {}
public void beforeTestMethod(TestContext arg0) throws Exception {}
public void prepareTestInstance(TestContext arg0) throws Exception {
// TODO Auto-generated method stub
String path = System.getProperty("java.class.path").split(";")[1];
path = path.substring(0,path.lastIndexOf("classes"));
ProtectionCheck.getInstance().init(path+"/conf/license");
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值