Spring会话bean将FacesContext.getCurrentInstance()视为空引用
我有一个Spring会话bean将FacesContext.getCurrentInstance()视为空引用,spring,jsf,jsf-2.2,Spring,Jsf,Jsf 2.2,我有一个Actor类来处理用户会话范围内的数据 import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component(value = "actor") @Scope(value = "session") public class Actor{ public Actor() {
Actor
类来处理用户会话范围内的数据
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component(value = "actor")
@Scope(value = "session")
public class Actor{
public Actor() {
System.out.println("Inside void init Actor..........");
System.out.println(JsfUtils.getFacesContext());// This prints Null
}
}
web.xml
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
Facesservlet
javax.faces.webapp.FacesServlet
1.
Facesservlet
*.html
org.springframework.web.context.ContextLoaderListener
org.springframework.web.context.request.RequestContextListener
applicationContext.xml
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">
<context:load-time-weaver aspectj-weaving="off" />
<task:scheduler id="taskScheduler"/>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="8" />
<property name="queueCapacity" value="2000" />
</bean>
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler"/>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="contextApplicationContextProvider" class="net.main.spring.context.ApplicationContextProvider"></bean>
// <context:component-scan base-package="net.main.x">//</context:component-scan> more goes here
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Default_Persistence_Unit"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
<property name="showSql" value="false"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</property>
</bean>
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="jpaTransactionManager" proxy-target-class="true"/>
</beans>
////这里还有更多
在以前的项目中,它工作得很好,所以我认为JSF的版本是我使用Spring4.1.4版本2.2.12的原因。我试图降级JSF版本或升级Spring版本,但没有成功。另一个问题是Actor
构造函数被多次调用
这里是否有隐藏的行为,Spring应该看到FacesContext
,因为请求是由jsfservlet映射的,还是不能看到,因为FacesContext
在另一个作用域中
我假设Spring是在JSF之前初始化的,因此它会将FacesContext
视为空值,如果是这样,那么如何订购初始化容器
提前谢谢我的
日志dinfilter
没有发布在问题上
public class LoggedInFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
Actor actor = SpringUtils.getBean(Actor.class);
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
boolean isAdminPage = uri.contains("/cpanel/");
if (!actor.isLoggedIn() && (uri.contains("/select-issue") || isAdminPage)) {
request.getRequestDispatcher("/login.html").forward(request, response);
} else if (isAdminPage) {
if (actor.isAdmin()) {
chain.doFilter(request, response);
} else {
res.sendRedirect("/404.html");
}
} else {
chain.doFilter(request, response);
}
} catch (Exception ex) {
SystemLogger.getLogger(getClass().getSimpleName()).error(ex.getMessage());
}
}
挖掘问题发现原因在于过滤器
筛选器无法查看FacesContext
原因facesservlet
尚未在筛选器作用域上初始化有关详细信息,请参阅此
因此,当在过滤器上注入actor时,它的构造函数开始,如果您试图在此时使用FacesContext
,就会抛出BAMNullPointerException
我的错误我真的不认为过滤器会影响对问题的理解,因此我可以看出,没有人能够首先解决问题对不起,为什么那些听众映射/注册了两次?您真的需要将FacesServlet
映射到*.html
?并在@PostConstruct
@Tiny中初始化bean。对不起,我的错误,我将进行编辑it@Tiny是的,我需要所有的请求都是JSF范围的,并且使用PostConstruct
具有和构造函数相同的效果,这会有什么不同吗,当您将这两个侦听器放在web.xml
中的javax.faces.webapp.FacesServlet
之前时,我猜Spring正在构建您的Actor
bean,因此它与任何JSF请求都没有关系。好的,在JSF生命周期之外不能访问faces上下文,所以这个方法应该返回空值。但是,您应该能够使用标准servlet API访问JSF会话和应用程序管理的bean来检索它们。