How to configure spring webflow with jsf 2.0?

为君一笑 提交于 2019-12-01 06:22:26

问题


I have a problem integration JSF2.0 as a view technology to spring webflow. I managed to get it "almost" working, the only thing left is configuring ajax support for JSF2.0.

Ajax requests are sent, responses from the server are received, but the response doesn't trigger re-rendering of the component.

Few clues to help to solve the problem:

  • When it comes to generating .js links to resources, JSF behavior is wrong. JSF tries to access the following link:

    http://localhost:8080/${context_path}/${flow_name}/javax.faces.resource/jsf.js?ln=javax.faces This gives 404 back. I had to hard-code the following link in the template to get some of the ajax support:

    http://localhost:8080/${context-path}/javax.faces.resource/jsf.js.faces?ln=javax.faces (I found this link after switching the web-flow off and investigating the source code of plain JSF processed page)

  • I assume, that the configuration of JSF is correct. If I drop the webflow from the processing chain, everything works as expected. Links are OK, re-rendering of the component is OK

  • If I expose my services as @ManagedBean (JSF native approach) and don't use Spring backed beans re-rendering works fine, but I'm not able to interact with webflow and flow scoped variables (web-flow doesn't see native @ManagedBeans) and still I have to use the hard-coded links.

  • I don't have any Spring resource servlet / filter. I don't use urlRewrite rules to forward to my flows.

If config files are required - I will post them in the question.

Any help is appreciated. Seems that this is a blocking issue of using the whole technology stack.


回答1:


Step :1 web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
        <display-name>JSF2.0 with Spring webflow</display-name>

    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/config/web-application-config.xml
            </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>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
            <param-value>1</param-value>
        </context-param>

    <filter>
            <filter-name>charEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>

        <filter-mapping>
            <filter-name>charEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

        <servlet>
            <servlet-name>facesServlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet-mapping>
            <servlet-name>facesServlet</servlet-name>
            <url-pattern>/faces/*</url-pattern>
        </servlet-mapping>
        <servlet-mapping>

            <servlet-name>facesServlet</servlet-name>
            <url-pattern>*.jsf</url-pattern>
        </servlet-mapping>

        <servlet-mapping>
            <servlet-name>facesServlet</servlet-name>
            <url-pattern>*.faces</url-pattern>
        </servlet-mapping>

        <servlet-mapping>
            <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
        </servlet-mapping>
<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>2</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.web.context.ContextLoaderListener</listener-class>
    </listener>

     <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

     <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener> 
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

Step: 2 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">
        </faces-config>

Step: 3 webflow-config.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: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/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">

    <!-- Executes flows: the central entry point into the Spring Web Flow system -->
    <webflow:flow-executor id="flowExecutor">
        <webflow:flow-execution-repository max-executions="1" />
        <webflow:flow-execution-attributes>
            <webflow:always-redirect-on-pause value="true"/>
        </webflow:flow-execution-attributes>
        <webflow:flow-execution-listeners>
            <webflow:listener ref="securityFlowExecutionListener"/>
            <webflow:listener ref="facesContextListener"/>
        </webflow:flow-execution-listeners>
    </webflow:flow-executor>

    <!-- The registry of executable flow definitions -->
    <webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF/flows">
        <webflow:flow-location-pattern value="/**/*-flow.xml" />
    </webflow:flow-registry>

    <!-- Configures the Spring Web Flow JSF integration -->
    <faces:flow-builder-services id="facesFlowBuilderServices" development="true" />

    <!-- Installs a listener to apply Spring Security authorities -->
    <bean id="securityFlowExecutionListener" class="org.springframework.webflow.security.SecurityFlowExecutionListener"/>

        <!-- Installs a listener that creates and releases the FacesContext for each request. -->
    <bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>


</beans>

Step :4 webmvc-config.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: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/faces http://www.springframework.org/schema/faces/spring-faces-2.4.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <faces:resources />

    <!-- Maps request URIs to controllers.  Here we have two kinds of flows one  is login flow and another is main flow   -->           
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
                /main=flowController
               </value>
        </property>
        <property name="defaultHandler">
            <!-- Selects view names to render based on the request URI: e.g. /main selects "main" -->   
            <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
        </property>
    </bean>

    <!-- it is used to handle the flow control Adaptor in 2.3.0.   This will come from spring framework.web.servlet3.2.1 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

    <!-- Handles requests mapped to the Spring Web Flow system and ajaxHandler.
    after security we need to enable the ajax for that we need to write one property i.e ajaxHandler -->
    <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
        <property name="flowExecutor" ref="flowExecutor" />
         <property name="ajaxHandler">
        <bean class="org.springframework.faces.webflow.JsfAjaxHandler"/>
    </property>
    </bean>

    <!-- Maps logical view names to Facelet templates in /WEB-INF (e.g. 'search' to '/WEB-INF/search.xhtml' -->
    <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="facesContextListener"  class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />


</bean>

</beans>



回答2:


Recently I made a migration from JSF 1 to JSF 2 in a spring webflow project. Later I figured out that ajax doesn't work. I had these two beans configured in webmvc-config.xml

The first bean was the problem

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor"/>
</bean>

<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor" />
</bean>

You cant' have them both. So make sure you have only JsfFlowHandlerAdapter

<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor" />
</bean>

Here are some framework versions in my project just in case

    <spring.version>3.2.13.RELEASE</spring.version>
    <jsf.version>2.2.8-02</jsf.version>
    <org.springframework.webflow>2.4.0.RELEASE</org.springframework.webflow>
    <org.springframework.security.version>3.2.4.RELEASE</org.springframework.security.version>


来源:https://stackoverflow.com/questions/4825904/how-to-configure-spring-webflow-with-jsf-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!