JSF2:从 Spring 向 managedbean 注入服务对象?
Posted
技术标签:
【中文标题】JSF2:从 Spring 向 managedbean 注入服务对象?【英文标题】:JSF2 : inject service objects to managedbean from Spring? 【发布时间】:2011-06-11 02:21:49 【问题描述】:我已经对此进行了测试,尝试将服务对象注入@ManagedBean,但失败并出现空指针异常,因为 userService 为空。
我目前使用的是 Tomcat 7、JSF 2,这是我的一些 pom.xml
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.0.3.RELEASE</org.springframework-version>
<org.hibernate-version>3.6.0.Final</org.hibernate-version>
....
</properties>
这是异常跟踪:
javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:558)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Caused by: java.lang.NullPointerException
at org.albertkam.ui.LoginBean.login(LoginBean.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 23 more
这是我的 ManagedBean:
@ManagedBean
@RequestScoped
public class LoginBean
private MstUser entityMstUser;
@Autowired
private UserService userService;
@PostConstruct
private void init()
this.entityMstUser = new MstUser();
这是我的服务 bean ..
@Service
public class UserService
@Autowired
private UserDAO userDao;
public void login(MstUser entityMstUser)
这是我的 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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
default-autowire="byName">
<context:component-scan base-package="org.albertkam" />
<context:annotation-config />
<tx:annotation-driven />
</beans>
还有我的 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>albert simpleWebapp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/datasourceContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
还有我的 faces-config.xml,虽然这里真的没有什么相关的..
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>in</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
<resource-bundle>
<base-name>org.albertkam.common.messages</base-name>
<var>msgs</var>
</resource-bundle>
<resource-bundle>
<base-name>org.albertkam.common.errors</base-name>
<var>errs</var>
</resource-bundle>
<!-- <message-bundle>id.co.sofcograha.override_messages</message-bundle> -->
</application>
<factory>
<exception-handler-factory>org.albertkam.common.BusinessExceptionHandlerFactory</exception-handler-factory>
</factory>
</faces-config>
我想知道是否可以做这样的事情,将 Spring 托管 bean 注入 @ManagedBean ?
请分享您在这方面的经验..
谢谢!
***********添加了一些新的实验结果******************
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>Hello,
我已经对此进行了测试,尝试将服务对象注入@ManagedBean,但失败并出现空指针异常,因为 userService 为空。
我目前使用的是 Tomcat 7、JSF 2,这是我的一些 pom.xml
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.0.3.RELEASE</org.springframework-version>
<org.hibernate-version>3.6.0.Final</org.hibernate-version>
....
</properties>
这是异常跟踪:
javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:558)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Caused by: java.lang.NullPointerException
at org.albertkam.ui.LoginBean.login(LoginBean.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 23 more
这是我的 ManagedBean:
@ManagedBean
@RequestScoped
public class LoginBean
private MstUser entityMstUser;
@Autowired
private UserService userService;
@PostConstruct
private void init()
this.entityMstUser = new MstUser();
这是我的服务 bean ..
@Service
public class UserService
@Autowired
private UserDAO userDao;
public void login(MstUser entityMstUser)
这是我的 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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
default-autowire="byName">
<context:component-scan base-package="org.albertkam" />
<context:annotation-config />
<tx:annotation-driven />
</beans>
还有我的 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>albert simpleWebapp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/datasourceContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
还有我的 faces-config.xml,虽然这里真的没有什么相关的..
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>in</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
<resource-bundle>
<base-name>org.albertkam.common.messages</base-name>
<var>msgs</var>
</resource-bundle>
<resource-bundle>
<base-name>org.albertkam.common.errors</base-name>
<var>errs</var>
</resource-bundle>
<!-- <message-bundle>id.co.sofcograha.override_messages</message-bundle> -->
</application>
<factory>
<exception-handler-factory>org.albertkam.common.BusinessExceptionHandlerFactory</exception-handler-factory>
</factory>
</faces-config>
我想知道是否可以做这样的事情,将 Spring 托管 bean 注入 @ManagedBean ?
请分享您在这方面的经验..
谢谢!
***********添加了一些新的实验结果******************
刚刚我尝试使用@Named 替换@ManagedBean 和@Inject 替换@Autowired,并且成功了,虽然我仍然不明白其中的原因。
这是修改后的托管 bean:
@Named("userBean")
@RequestScoped
public class LoginBean
private MstUser entityMstUser;
@Inject
private UserService userService;
@PostConstruct
private void init()
this.entityMstUser = new MstUser();
这行得通,服务对象被注入了,虽然 userService 是由 Spring 管理的?这怎么可能?
这是我在此过程中添加的一些其他内容..
我在 web.xml 中添加了这个
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
我还添加了一个空的 WEB-INF/beans.xml
这在 faces-config.xml 中 org.springframework.web.jsf.el.SpringBeanFacesELResolver
我有点担心使用@Named,因为我有一个bad experience 将它与ViewScoped 一起使用。当我让 @ManagedBean 能够被 Spring 框架注入服务对象时,我会感觉更安全。
我想知道你们通常用 CDI 或纯 Spring 或它们的组合将 ManagedBean 与业务服务对象连接起来吗?
【问题讨论】:
【参考方案1】:例如,在您的应用程序上下文 xml 中为“UserService”定义一个 bean,
<bean id="userService" class="org.albertkam.yourclassname"/>
【讨论】:
【参考方案2】:faces-config.xml
中缺少变量解析器
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
web.xml
中缺少 RequestContextListener 侦听器
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
【讨论】:
您好,感谢您的快速回复。我在原帖中添加了一些细节。如果我错了,请纠正我,但 DelegatingVariableResolver 是为了让我可以#springBeanName,而 RequestContextListener 是为了让我不再需要使用@ManagedBean,而是我可以在 spring xml 中定义 bean 或使用 @Component on bean,避免使用 2 个不同的容器(jsf 和 spring)来处理 bean。但我更喜欢让 JSF 处理 @ManagedBean,并让 Spring 向 ManagedBean 注入服务 bean。我尝试添加您提到的那些,但仍然失败。 我在faces-config.xml
中看不到变量解析器,它用于解析您注入的任何依赖项。这样如果在 jsf 的上下文中找不到,您的 jsf 容器就会在 spring 的上下文中进行查找
啊抱歉,我忘了提到我也添加了这个@faces-config.xml:以上是关于JSF2:从 Spring 向 managedbean 注入服务对象?的主要内容,如果未能解决你的问题,请参考以下文章