使用struts2,下面为action代码
Java代码
package com.edar.web.platform; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.InterceptorRefs; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.edar.components.AccountBean; import com.edar.dao.util.Page; import com.edar.model.Account; import com.edar.service.platform.AccountService; import com.edar.web.struts2.GenericAction; @Component @Namespace("/platform") @InterceptorRefs( { @InterceptorRef("paramsPrepareParamsStack") }) @Results( { @Result(name = GenericAction.RELOAD, location = "account.action", type = "redirect") }) public class AccountAction extends GenericAction<AccountBean> { private static final long serialVersionUID = 1900042912756344244L; @Autowired @Qualifier("accountServiceImpl") private AccountService accountService; private AccountBean accountBean; private Page<AccountBean> page = new Page<AccountBean>(16,true); public AccountBean getAccountBean() { return accountBean; } public void setAccountBean(final AccountBean accountBean) { this.accountBean = accountBean; } public Page<AccountBean> getPage() { return page; } public void setPage(final Page<AccountBean> page) { this.page = page; } @Override public String delete(){ accountService.delete((Account) dozer.map(accountBean, Account.class)); return SUCCESS; } @Override public String list(){ page = accountService.getPage(accountBean); return SUCCESS; } @Override protected void prepareModel(){ if(accountBean==null){ accountBean = new AccountBean(); }else{ if(accountBean.getAccountId()!=null){ accountBean = (AccountBean)dozer.map(accountService.getAccount(accountBean.getAccountId()), AccountBean.class); } } } @Override public String save(){ Account account = (Account) dozer.map(accountBean, Account.class); accountService.save(account); accountBean.setAccountId(account.getAccountId()); return SUCCESS; } public AccountBean getModel() { return accountBean; } }
此action的junit测试代码
package com.edar.web.platform; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.edar.components.AccountBean; import com.edar.test.SpringContextTestCase; public class AccountActionTest extends SpringContextTestCase{ private static Long accountId; @Autowired private AccountAction accountAction; @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Before public void setUp() throws Exception { AccountBean bean = new AccountBean(); bean.setName("ysheng53"); bean.setMobile("13819181747"); bean.setEmail("ysheng53@gmail.com"); bean.setPasswd("321"); accountAction.setAccountBean(bean); } @After public void tearDown() throws Exception { } @Test public void testSave() { String result = accountAction.save(); accountId = accountAction.getAccountBean().getAccountId(); Assert.assertEquals(AccountAction.SUCCESS, result); } @Test public void testList() { String result = accountAction.list(); Assert.assertEquals(AccountAction.SUCCESS, result); Assert.assertTrue(" 结果数小于0了 ",accountAction.getPage().getTotal()>0); } @Test(timeout=5000) public void testDelete() { accountAction.getAccountBean().setAccountId(accountId); String result = accountAction.delete(); Assert.assertEquals(AccountAction.SUCCESS, result); Assert.assertTrue("<=0",accountAction.getPage().getTotal()<=0); } }
注意到action中的代码:
Java代码
@Autowired @Qualifier("accountServiceImpl") private AccountService accountService;
现象时,在junit测试代码执行时,accountService能够被注入,但是用tomcat6,在eclipse,wtp中启动时,accountService没有被注入,为null!
问题在查,谁遇到过类似问题;
问题补充
经过测试分析发现:
AccountAction在junit测试时用spring注入进去,而且只有唯一一个;
而在struts2中,每次请求都会有一个AccountAction的实例;
现在的问题是,struts2中新建实例时,那个private AccountService accountService;自动注入无效;
注:使用了Conventian Plugin
1 楼
sys53
2010-02-22
经过大量测试
发现struts2-spring没有配置好;
加上相应的包,同时objectFactory设为spring就解决了;
发现struts2-spring没有配置好;
加上相应的包,同时objectFactory设为spring就解决了;
2 楼
volking
2010-06-05
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。
属性注入null,怎么解决呢?
属性注入null,怎么解决呢?
3 楼
volking
2010-06-05
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。
属性注入null, 怎么解决呢?
注:我已经把struts2-spring-plugin放入lib里.
属性注入null, 怎么解决呢?
注:我已经把struts2-spring-plugin放入lib里.
4 楼
sys53
2010-06-09
volking 写道
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。
属性注入null, 怎么解决呢?
注:我已经把struts2-spring-plugin放入lib里.
属性注入null, 怎么解决呢?
注:我已经把struts2-spring-plugin放入lib里.
struts.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.convention.default.parent.package" value="crud-default" /> <constant name="struts.convention.package.locators" value="web" /> <!-- 用于CRUD Action的parent package --> <package name="crud-default" extends="convention-default"> <!-- 基于paramsPrepareParamsStack, 增加store interceptor保证actionMessage在redirect后不会丢失 --> <interceptors> <interceptor-stack name="crudStack"> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> <interceptor-ref name="paramsPrepareParamsStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="crudStack" /> </package> <!-- 使用Convention插件,实现约定大于配置的零配置文件风格. 特殊的Result路径在Action类中使用@Result设定. --> </struts>
struts.properties配置如下:
struts.devMode = true struts.locale=zh_cn struts.i18n.encoding=utf-8 struts.objectFactory=spring
如未解决,请你贴一下你的配置以及相关spring,struts2的包