How to configure spring webflow with jsf 2.0?
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.
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>
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>
精彩评论