我在演示应用程序中使用JSF2 + Spring3.1 + Hibernate4,我将要使用批注创建会话工厂,但我的DAO类未在Jsf Managed Bea类中初始化,因此我得到了Null指针异常。我的 applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.otv"></context:component-scan> <!-- Data Source Declaration --> <bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > <property name="driverClass" value="org.postgresql.Driver" /> <property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/postgres" /> <property name="user" value="postgres" /> <property name="password" value="hariom" /> <property name="maxPoolSize" value="10" /> <property name="maxStatements" value="0" /> <property name="minPoolSize" value="5" /> </bean> <!-- Session Factory Declaration --> <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean "> <property name="dataSource" ref="DataSource" /> <property name="annotatedClasses"> <list> <value>com.otv.model.User</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="packagesToScan" value="com.otv.user"></property> </bean> <!-- Transaction Manager is defined --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" > <property name="sessionFactory" ref="SessionFactory"/> </bean> <!-- Enable the configuration of transactional behavior based on annotations --> <tx:annotation-driven transaction-manager="txManager"/> </beans>
UserDAO.java类
package com.otv.user.dao; import java.util.List; import com.otv.model.User; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; /** * * User DAO * * @author onlinetechvision.com * @since 25 Mar 2012 * @version 1.0.0 * */ @Repository @Transactional public class UserDAO { @Autowired private SessionFactory sessionFactory; /** * Get Hibernate Session Factory * * @return SessionFactory - Hibernate Session Factory */ /* public SessionFactory getSessionFactory() { return sessionFactory; } *//** * Set Hibernate Session Factory * * @param SessionFactory - Hibernate Session Factory *//* public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }*/ /** * Add User * * @param User user */ public void addUser(User user) { sessionFactory.getCurrentSession().save(user); } /** * Delete User * * @param User user */ public void deleteUser(User user) { sessionFactory.getCurrentSession().delete(user); } /** * Update User * * @param User user */ public void updateUser(User user) { sessionFactory.getCurrentSession().update(user); } /** * Get User * * @param int User Id * @return User */ public User getUserById(int id) { List list = sessionFactory.getCurrentSession() .createQuery("from User where id=?") .setParameter(0, id).list(); return (User)list.get(0); } /** * Get User List * * @return List - User list */ public List<User> getUsers() { List list = sessionFactory.getCurrentSession().createQuery("from User").list(); return list; } }
和我的ManagedBean类
package com.otv.managed.bean; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.RequestScoped; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import com.otv.model.User; import com.otv.user.dao.UserDAO; import com.otv.user.service.IUserService; /** * * User Managed Bean * * @author onlinetechvision.com * @since 25 Mar 2012 * @version 1.0.0 * */ @ManagedBean(name="userMB") @RequestScoped public class UserManagedBean implements Serializable { private static final long serialVersionUID = 1L; private static final String SUCCESS = "success"; private static final String ERROR = "error"; //Spring User Service is injected... List<User> userList; private int id; private String name; private String surname; @Autowired private UserDAO userDAO; /** * Add User * * @return String - Response Message */ public String addUser() { try { User user = new User(); user.setId(getId()); user.setName(getName()); user.setSurname(getSurname()); userDAO.addUser(user); return SUCCESS; } catch (DataAccessException e) { e.printStackTrace(); } return ERROR; } /** * Reset Fields * */ public void reset() { this.setId(0); this.setName(""); this.setSurname(""); } /** * Get User List * * @return List - User List */ public List<User> getUserList() { userList = new ArrayList<User>(); userList.addAll(userDAO.getUsers()); return userList; } /** * Get User Service * * @return IUserService - User Service */ /** * Set User List * * @param List - User List */ public void setUserList(List<User> userList) { this.userList = userList; } /** * Get User Id * * @return int - User Id */ public int getId() { return id; } /** * Set User Id * * @param int - User Id */ public void setId(int id) { this.id = id; } /** * Get User Name * * @return String - User Name */ public String getName() { return name; } /** * Set User Name * * @param String - User Name */ public void setName(String name) { this.name = name; } /** * Get User Surname * * @return String - User Surname */ public String getSurname() { return surname; } /** * Set User Surname * * @param String - User Surname */ public void setSurname(String surname) { this.surname = surname; } }
现在在Managedbean方法中,DAO对象为null,并且我得到了Null Pointer异常
警告:#{userMB.addUser}:java.lang.NullPointerException javax.faces.FacesException:#{userMB.addUser}:com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118上的java.lang.NullPointerException )的javax.faces.component.UICommand.broadcast(UICommand.java:315)的javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)的javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java: 1259)位于com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)位于com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)位于com.sun.faces.lifecycle.LifecycleImpl org.apache.catalina.core.ApplicationFilterChain的javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)的.execute(LifecycleImpl.java:118)。org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)的internalDoFilter(ApplicationFilterChain.java:305)org.apache的org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)上的.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java :168),位于org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927),位于org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927),位于org.apache.catalina.valves.ErrorReportValve.java:98。位于org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)在org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:585)在org.apache.tomcat.util.net .JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:312)在java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908) )在java.lang.Thread.run(Thread.java:662)造成原因:javax.faces.el.EvaluationException:在javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)的java.lang.NullPointerException com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)… 23更多原因:java。在com.otv.managed.bean.UserManagedBean.addUser(UserManagedBean.java:57)处的lang.NullPointerException在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)处org.apache.el.parser.AstValue.invoke(AstValue.java:264)上java.lang.reflect.Method.invoke(Method.java:597)上的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)在org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)在com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)在javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter .java:88)…还有24个在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处的addUser(UserManagedBean.java:57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)处的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)处在org.apache.el.parser.AstValue.invoke(AstValue.java:264)在org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java)在java.lang.reflect.Method.invoke(Method.java:597) :278),位于com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105),位于javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)… 24更多在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处的addUser(UserManagedBean.java:57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)处的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)处在org.apache.el.parser.AstValue.invoke(AstValue.java:264)在org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java)在java.lang.reflect.Method.invoke(Method.java:597) :278),位于com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105),位于javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)… 24更多org.apache.el.parser.AstValue处的java.lang.reflect.Method.invoke(Method.java:597)处的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)处的invoke(NativeMethodAccessorImpl.java:39) org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)的com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)的.invoke(AstValue.java:264)。 faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)…还有24个org.apache.el.parser.AstValue处的java.lang.reflect.Method.invoke(Method.java:597)处的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)处的invoke(NativeMethodAccessorImpl.java:39) org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)的com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)的.invoke(AstValue.java:264)。 faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)…还有24个在com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)在javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)处调用(MethodExpressionImpl.java:278)… 24更多在com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)在javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)处调用(MethodExpressionImpl.java:278)… 24更多
简而言之,您的bean应该由JSF或Spring完全管理。
有很多证据表明这一点。只需在此处和/或在网上查找“ JSF +spring整合”即可。
现在让我考虑一下这个问题,以增进您的理解。
许多Web应用程序由应用程序的几个“层”组成,也称为“层”:Web层或表示层,用于查看应用程序的页面;业务层;或中间层,用于执行应用程序和数据层的逻辑和业务规则,或用于将数据传输到数据库或从数据库传输数据的持久层。这些层可能具有以下配置:
Entity
DAO
Service
Bean
下一步是为Web应用程序选择框架。
您为所有层选择Spring,这意味着您的DAO将是@Repository类,服务将是@Service类,而Beans将是@Component类。您很可能会使用像Hibernate这样的ORM框架来处理数据库,因此您的Entities将@Entity是以Hibernate样式正确配置的JPA 类。您的视图技术很可能是经过精心设计以与Spring核心一起使用的Spring MVC。例如,Mkyong有许多关于使用Spring的简单教程。
@Repository
@Service
@Component
@Entity
您为所有层选择本地JSF + EJB框架,这意味着您的DAO和服务将是@EJB类,而bean将是@ManagedBean类。您很可能还将Hibernate用作ORM解决方案和JPA提供程序,并将通过进行数据库访问EntityManager。您的视图技术将是JSF,因为它原本打算与上述技术一起使用。例如,BalusC有许多关于使用JSF的启发性教程。
@EJB
@ManagedBean
EntityManager
两种选择都有其倡导者和反对者。有的人说为什么选择不是 Sun的 Oracle解决方案所固有的东西,有的人说这太复杂和令人困惑,并且缺乏可学习的资源。
因为这在技术选择上没有争议,所以在此不做详细介绍,但要指出的是,Spring是一个轻量级的容器,可以在像Tomcat这样的简单servlet容器上运行,而EJB需要像Glassfish这样的应用程序服务器才能运行。我认为这是将JSF作为基于组件的Web框架并将Spring作为轻量级依赖注入和业务层框架相结合的主要推动力。
当我们决定将两个框架集成在一起时,我将解释该集成如何工作以及为什么会出现NPE。
@Transactional
@Scope("value")
@Autowired
因此,NPE源自误解,即您的bean作为视图的逻辑部分应由JSF管理(请注意,这@ManagedProperty也无法正常工作)。该bean由JSF实例化,但是您的服务驻留在JSF知道的Spring上下文中,因此无法进行注入。另一方面,如果bean仍在Spring上下文中,则它的生命周期和依赖关系将由Spring注入。
@ManagedProperty
因此,要使其工作,请将bean标记为
@Component @Scope("request") public class SpringManagedBeanToBeUsedByJSF { ... @Autowired private SpringService springService; ... }
并做好将Spring与JSF结合使用的所有先决条件。如果您迷路了,请参考此出色的示例进行设置。这样,当您在faces-config.xml中附加EL- resolver(允许JSF“查看” Spring Bean)和web.xml中的必要侦听器时,所有bean都将由Spring管理,并在JSF视图中可见。当您这样做时,所有的Spring Bean都可以在.xhtml文件中引用,并且如果您需要将JSF操作放入Bean中,只需继续将它们放入(Spring)托管的Bean中,或使其变得至关重要即可到JSF接口等。只能通过这种方式实现集成。当然,您也可以使用JSF托管Bean,@FacesConverter并且@FacesValidator 应用程序中的类也不会相互干扰,但是将两个依赖注入框架与一个应用程序一起使用至少会造成混淆。
@FacesConverter
@FacesValidator
希望这可以帮助您更好地了解情况。
您的代码中也存在一些问题,我不会在此一般性回答中强调。