JSF ManagedBean - 注入的属性在STATE_SAVING_METHOD = client上无法正常工作

时间:2012-04-03 02:02:10

标签: spring jsf viewstate mybatis managed-bean

我从两天开始陷入困境,我无法摆脱这个问题。

我遇到的问题是在反序列化后使用MangedBean属性(我猜) 使用Spring设置属性(purchaseManager),并使用DAO将MyBatis扩展为数据映射器以与DB交互。
实际上,在第一次访问页面时,init()方法中的purchaseManager.getAll()工作正常 当我尝试从按钮调用refreshList()作为动作时,我在DAO内的getSqlSession()上有一个NullPointerException。

只让相关代码的情况如下:

@ManagedBean(name = "purchaseController")
@ViewScoped
public class PurchaseController implements Serializable{

    @ManagedProperty(value = "#{purchaseManager}")
    private PurchaseManager purchaseManager;

    @PostConstruct
    public void init(){
        purchaseManager.getAll();
    }

    public void refreshList(){
        purchaseManager.getAll();
    }
}

public class PurchaseManagerImpl implements PurchaseManager, Serializable {
    PurchaseDAO purchaseDAO;

    public void getAll() {
        purchaseDAO.getAll()
    }
}

public class PurchaseDAOImpl extends SqlSessionDaoSupport implements PurchaseDAO, Serializable {

    public void getAll() {
        SqlSession session = getSqlSession();  // when the call comes from refreshList(), session is null
        session.selectList("PAYMENT.getAll", null);
    }
}

in web.xml
<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
</context-param>

如果我将STATE_SAVING_METHOD更改为服务器,应用程序工作正常,但不是我想要的。如果我将ManageBean作为RequestScope,同样的事情,但这也会影响我的要求。

提前感谢任何人提供任何帮助! Ermal

1 个答案:

答案 0 :(得分:0)

解决了将<aop:scoped-proxy proxy-target-class="false" />添加到通过Spring声明的服务/管理器定义的错误。这使得注入完全可序列化的代理实例成为可能。

<bean id="purchaseManager" class="al.ozone.bl.manager.impl.PurchaseManagerImpl">    
    <property name="purchaseDAO" ref="purchaseDAO" />   
    <aop:scoped-proxy proxy-target-class="false" />
</bean> 

proxy-target-class="false"用于告知PurchaseManagerImpl已实现接口。如果设置为true或省略,则必须使用CGLIB2库。

通过这种方式,JSF使用Spring + MyBatis正确地从数据库中获取数据。

关于这一点(更理论上)的错误(对我来说)是:

  • MyBatis对象(PurchaseDAOImpl)和dataSource是否在幕后正确处理?
  • 是在每个HTTP请求上重新创建还是还原?

请记住,我STATE_SAVING_METHOD=client和BackingBean为ViewScope。我的目标是让服务器更轻便,因为我希望用户互动量很大。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="poolPreparedStatements" value="true" />
    <property name="defaultAutoCommit" value="false" />
</bean>

非常感谢任何人对此事有所了解!

咨询链接:

Spring session-scoped beans (controllers) and references to services, in terms of serialization

http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection

http://www.infoq.com/presentations/Whats-New-in-Spring-3.0