1

我正在使用 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 使用范围 Session 管理 bean,但它也不起作用。另一个需要注意的是,默认值在页面上正确显示。

编辑#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 演示相同的方式进行调试,仅触发一个不返回状态 302 的 POST 请求

谢谢

4

3 回答 3

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 请求后完全刷新页面。

于 2012-08-15T15:27:08.527 回答
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 更新时动态呈现页面元素。

于 2012-08-01T00:00:59.323 回答
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 就像魔法一样工作(因为我不知道我是什么所以需要这样做正在做)

于 2021-03-03T16:33:05.920 回答