我正在使用Spring 3.2.0,PrimeFaces 3.3.1,Mojarra 2.1.11和Spring Security 3.1.1创建一个项目。
我的问题是当PrimeFaces触发ajax调用时,例如在表格分页中,屏幕组件不会刷新。
编辑#4
每当调用ajax时,都会从服务器返回错误302并刷新页面
我认为问题与Spring安全有关,这是我的设置:
<security:http entry-point-ref="authenticationEntryPoint" pattern="/spring/**">
<security:anonymous />
<security:http-basic />
<security:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />
<security:logout logout-url="/spring/logout" logout-success-url="/spring/login?logout=true" />
<security:intercept-url pattern="/spring/login" access="ROLE_ANONYMOUS,ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/spring/logoutSuccess" access="ROLE_ANONYMOUS,ROLE_USER,ROLE_CLIENT" />
<security:intercept-url pattern="/spring/intro" access="ROLE_ANONYMOUS,ROLE_USER" />
<security:intercept-url pattern="/spring/flows/admin_main_flow/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/spring/flows/client_main_flow/**" access="ROLE_CLIENT" />
</security:http>
<security:http security="none" pattern="/javax.faces.resource/**" />
<security:http security="none" pattern="/ajax/**" />
<security:http security="none" pattern="/static/**" />
<security:http security="none" pattern="/resources/**" />
这是在登录后发生的,所以我认为会话不应该已经过期。
编辑#4结束
我将应用程序剥离到最低限度并尝试使用此代码:
<h:form id="testAjax" >
<h:panelGrid columns="4" cellpadding="5">
<h:outputLabel for="test" value="test:" style="font-weight:bold"/>
<p:inputText id="test" value="#{testBean.test}" />
<p:commandButton value="Submit" update="@form"/>
<h:outputText value="#{testBean.test}" id="display" />
</h:panelGrid>
</h:form>
请注意,我仔细检查过没有嵌套的表单,我尝试使用@form或元素id进行“处理”和“更新”。
会发生的是调用TestBean的setter,设置属性,但是再也不会再调用getter来显示新值。这是服务器端的日志:
org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Spring MVC Dispatcher Servlet' processing POST request for [/TryAjax/spring/WEB-INF/login.xhtml]
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/WEB-INF/login.xhtml] to HandlerExecutionChain with handler [org.springframework.web.servlet.mvc.UrlFilenameViewController@2f46ccac] and 1 interceptor
org.springframework.web.servlet.mvc.UrlFilenameViewController - Returning view name 'WEB-INF/login' for lookup path [/WEB-INF/login.xhtml]
org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.faces.mvc.JsfView: name 'WEB-INF/login'; URL [/WEB-INF/WEB-INF/login.xhtml]] in DispatcherServlet with name 'Spring MVC Dispatcher Servlet'
org.springframework.faces.support.RequestLoggingPhaseListener - Entering JSF Phase: RESTORE_VIEW 1
org.springframework.faces.mvc.JsfView - Asking faces lifecycle to render
org.springframework.faces.support.RequestLoggingPhaseListener - Entering JSF Phase: RENDER_RESPONSE 6
org.springframework.faces.mvc.JsfView - View rendering complete
org.springframework.web.servlet.DispatcherServlet - Successfully completed request
我担心是配置问题,我按照基本指令但是做了一些修改来纠正一些错误,这里的web.xml剥离了一些不相关的部分
<?xml version = '1.0'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring_context.xml</param-value>
</context-param>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener </listener-class>
</listener>
<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>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/tags/synaptic.taglib.xml</param-value>
</context-param>
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
<context-param>
<param-name>facelets.SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Resources Servlet</servlet-name>
<servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resources Servlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
</web-app>
面对配置
<?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>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
其他弹簧流配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<faces:resources />
<context:annotation-config />
<context:component-scan base-package="com.synaptic"/>
<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/flows/*=flowController
</value>
</property>
<property name="defaultHandler">
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">
</bean>
<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".xhtml"/>
</bean>
<bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="flowFacesContextLifecycleListener" />
<!-- <webflow:listener ref="facesContextListener"/>-->
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<bean id="flowFacesContextLifecycleListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
<webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices">
<webflow:flow-location-pattern value="/WEB-INF/flows/**/*.xml"/>
</webflow:flow-registry>
<bean id="conversionService" class="org.springframework.faces.model.converter.FacesConversionService"/>
<bean id="expressionParser" class="org.springframework.webflow.expression.el.WebFlowELExpressionParser">
<constructor-arg>
<bean class="org.jboss.el.ExpressionFactoryImpl"/>
</constructor-arg>
<property name="conversionService" ref="conversionService"/>
</bean>
<faces:flow-builder-services id="facesFlowBuilderServices" expression-parser="expressionParser" conversion-service="conversionService"/>
</beans>
如果您发现任何错误或者您有任何想法可以帮助我,请解决这个问题。谢谢!
编辑#1
我添加了支持bean的代码和我声明它的webflow代码:
public class TestBean implements Serializable {
private String test = "xxx";
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
<view-state id="home" view="../views/adminHome.xhtml">
<on-entry>
<evaluate expression="textManager.getTest()" result="viewScope.test"/>
</on-entry>
</view-state>
现在这个testBean只是我可以做的最简单的测试用例,它不起作用,我遇到的主要问题是没有ajax调用,例如表的分页,添加或删除或修改数据表的元素,tabView等。
我通常为页面创建bean并将它们放在viewScope或flowScope中,这也适用于来自数据库的数据列表。我尝试使用Spring管理的bean使用范围Session,但它既不起作用也不起作用。另一个注意事项是页面上的默认值显示正确。
编辑#2
使用firebug和eclipse调试我看到了:
TestBean.test的初始值为“xxx”,我更改为aaa并按提交。
ajax post请求被发送到服务器:
javax.faces.ViewState e2s1
javax.faces.partial.ajax true
javax.faces.partial.execu... @all
javax.faces.partial.rende... testAjax testAjax:display
javax.faces.source testAjax:testButton
testAjax testAjax
testAjax:test aaa
testAjax:testButton testAjax:testButton
当发送POST时,我首先调试对TestBean.getTest()的调用,然后调用具有正确值的TestBean.setTest(“aaa”)。
此时我希望在构建响应时再次调用TestBean.getTest(),但调用没有发生且响应不包含正确的值,而是旧值“xxx”。
如果现在我刷新页面,则调用getter并正确显示新值“aaa”。
编辑#3
我仍然可以解决这个问题。我现在注意到了萤火虫出乎意料的行为:
当我单击命令按钮时,2请求被发送到服务器,POST和GET。
首先发送POST并返回错误“302 Moved Temporarily”,然后GET启动并返回没有更新数据的响应。任何人都知道在这种情况下302意味着什么,可能是什么原因?
以相同的方式调试primefaces演示只触发POST请求,返回无错误
谢谢
答案 0 :(得分:1)
您需要向flow-executor添加一个参数,以禁止重定向到相同的状态。配置变为:
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="flowExecutionListener" />
<webflow:listener ref="facesContextListener"/>
<!-- <webflow:listener ref="flowFacesContextLifecycleListener" />-->
</webflow:flow-execution-listeners>
<webflow:flow-execution-attributes>
<webflow:redirect-in-same-state value="false"/>
</webflow:flow-execution-attributes>
</webflow:flow-executor>
这可以防止流执行程序在发送ajax请求后完全刷新页面。
答案 1 :(得分:0)
当您将JSF与Spring集成时,您的JSF托管bean将成为Spring bean。这就是为什么Spring包含他们自己的ELResolver实现的原因,这样你就可以从EL表达式中引用这些Spring bean。
不幸的是,虽然Spring支持的唯一范围是@Request,@ Session和@Application。
幸运的是,可以将与Spring集成的ViewScope的简单实现集成到您的应用程序中。 PrimeFaces的首席开发人员Cagatay Civici撰写了一篇博客文章,展示了一个简单的ViewScope实现示例,该实现可以轻松集成到您的应用程序中。
http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/
使用视图作用域的托管bean,您的bean将具有足够的持久性,以便在ajax更新上动态呈现页面元素。
答案 2 :(得分:0)
<webflow:flow-execution-attributes>
<webflow:redirect-in-same-state value="false"/>
</webflow:flow-execution-attributes>
解决了我的问题。 我使用 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping 与 JSF 1.x RichFaces 3.x 导航。 当转移到 JSF 2.x 和 PrimeFaces/RichFaces 4 时,DataTables 的 ajax 方面不起作用(例如显示但不会排序) 添加这个 xml 就像魔法一样(因为我不知道我在做什么,所以需要这样做)