Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC integration in JSF2/Richfaces - possible? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC integration in JSF2/Richfaces - possible?

    Hi,

    I am currently working on a new project which requires strong use of AJAX. We evaluated some frameworks and are planning to implement it using JSF2 und JBoss Richfaces 3.3.3

    However, our customer gave the requirement to use a RESTful URL concept. Because Spring MVC 3.0 supports this, and we anyway will use Spring in the service layer, the idea came up to use Spring MVC for resolving incoming requests in combination with the JSF/RF view layer.

    I digged a bit in the web for Spring&JSF&RF integration examples. So far I found two different types of examples:

    a) Use a special ELResolver for getting access to SpringBeans in EL and as Controllers.
    b) Complete integration of Spring WebFlow and JSF/RF.

    Option a is definately not enough for us, because the main part is the RESTful-ness of URLs in Spring MVC.
    Option b seems to add way too much complexity in my opionion: We only need the view resolving from Spring MVC, not the complete WebFlow functionality. I would even prefer if for the JSF/Richfaces developers, the Spring MVC integration would be at most transparently as possible.

    I took some training in Spring, but never truely used it; so maybe I am missing some important point here.
    Can you give me please an advise or state if it is possible to use MVC 3.0 resolving without full WebFlow integration?

    Thank you very much in advance!

  • #2
    I got it running so far that:
    • Dispatcher Servlet is used for applying Spring @Controller
    • The JSF-view selected by the controller is correctly rendered by JSF + Richfaces
    • No Webflow is used

    But I have still strong problems:

    When Richfaces renders a reference to a resource for AJAX requests (usually the current page), this is the path where the XHTML-file is. I would require it to be the same path that the user requested originally, the same that matched my @RequestMapping annotation.

    Example:
    The user requests /spring/test/1 -> Resolved by Spring MVC to /WEB-INF/pages/test_1.xhtml
    All AJAX calls from richfaces on this page will request /WEB-INF/pages/test_1.xhtml directly and get a 404 error. Instead, it should request the same /spring/test/1 URL.

    I used a lot from the "Hotel Booking Sample" application, and there this seems to work. So I really begin to think that JSF2 or RF3.3.3 could be the problem here...

    Again, I would be grateful to get some help.
    Here are some relevant snippets:

    controller:
    Code:
    	@RequestMapping("/test/{nr}")
    	public String test(@PathVariable("nr") Long number) {
    		
    		if (number == null) {
    			return null;
    		}
    		
    		return "test_" + number;
    	}
    Web.xml
    Code:
      	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>/WEB-INF/spring/spring-config.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>/WEB-INF/spring/spring-config.xml</param-value>
    		</init-param>
    	</servlet>
    	
    	<servlet-mapping>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<url-pattern>/spring/*</url-pattern>
    	</servlet-mapping>
    
        <!-- default suffix for requested pages -->
        <context-param>
             <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
             <param-value>.xhtml</param-value>
         </context-param>
        
        <!-- filter for richfaces integration -->    
        <filter>
           <display-name>RichFaces Filter</display-name>
           <filter-name>richfaces</filter-name>
           <filter-class>org.ajax4jsf.Filter</filter-class>
        </filter>
    
    	<!-- integrates richfaces into spring requests -->
        <filter-mapping>
            <filter-name>richfaces</filter-name>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
        </filter-mapping>
    
    	<!-- integrates richfaces into jsf requests -->
        <filter-mapping>
            <filter-name>richfaces</filter-name>
            <servlet-name>Faces Servlet</servlet-name>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
        </filter-mapping>
    
        <listener>
            <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
        </listener>
    
        <!-- Faces Servlet -->
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!-- Faces Servlet Mapping -->
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.faces</url-pattern>
        </servlet-mapping>
    spring-config.xml
    Code:
    	<!-- Activates annotation-based bean configuration -->
    	<context:annotation-config />
    
    	<!-- Scans for application @Components to deploy -->
    	<context:component-scan base-package="com.any" />
    
    	<!-- Maps logical view names to Facelet templates (e.g. 'search' to '/WEB-INF/pages/search.xhtml' -->
    	<bean id="jsfViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    		<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    		<property name="prefix" value="/WEB-INF/pages/" />
    		<property name="suffix" value=".xhtml" />
    	</bean>

    Comment


    • #3
      JSF2 / RF3.3.3 should not be the reason. I changed the dependencies of my project to Spring 2.5.5, JSF1.2 and Richfaces 3.2.2. This is all equal to the Hotel Booking Sample - but it still has the exact same problem...

      Comment


      • #4
        Sorry for the monologue, but I think keeping my findings may help someone in the same situation.

        I got it now working by integrating Webflow fully - meaning I added one flow which's view is my JSF+RF page. The AJAX-references are correctly set to the initial URL.

        Another thing I noticed is that this is not compatible to JSF2, at least not without changes. When I tried it like in the Hotel Booking Sample, it works now with JSF1.2, but when I switch back the dependency to JSF2 I get a nice stacktrace. Accourding to JSF source, there have been changed to this method in JSF2, so this may be the reason.
        Code:
        SCHWERWIEGEND: Servlet.service() for servlet Spring MVC Dispatcher Servlet threw exception
        java.lang.UnsupportedOperationException
        	at javax.faces.context.FacesContext.getAttributes(FacesContext.java:141)
        	at com.sun.faces.util.RequestStateManager.get(RequestStateManager.java:194)
        	at com.sun.faces.util.Util.getFacesMapping(Util.java:564)
        	at com.sun.faces.application.view.MultiViewHandler.derivePhysicalViewId(MultiViewHandler.java:483)
        	at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:142)
        	at org.springframework.faces.webflow.FlowViewHandler.restoreFlowView(FlowViewHandler.java:128)
        	at org.springframework.faces.webflow.FlowViewHandler.restoreView(FlowViewHandler.java:75)
        	at com.sun.facelets.FaceletViewHandler.restoreView(FaceletViewHandler.java:316)
        	at org.ajax4jsf.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:107)
        	at org.springframework.faces.webflow.JsfViewFactory.getView(JsfViewFactory.java:93)
        	at org.springframework.webflow.engine.ViewState.resume(ViewState.java:193)
        	at org.springframework.webflow.engine.Flow.resume(Flow.java:545)
        	at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
        	at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:163)
        	at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
        	at org.springframework.webflow.mvc.servlet.FlowController.handleRequest(FlowController.java:174)
        	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
        	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
        	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
        	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
        	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        	at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
        	at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
        	at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
        	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
        	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
        	at java.lang.Thread.run(Thread.java:619)
        But that I really need to have Webflow integration and even JSF1 for the full Richfaces integration is of course the worst outcome for my purpose.

        Do you see another way to utilize Spring MVC (3.0 for REST) with RichFaces?

        Comment


        • #5
          Originally posted by xck3001 View Post
          I got it now working by integrating Webflow fully - meaning I added one flow which's view is my JSF+RF page. The AJAX-references are correctly set to the initial URL.
          How does your configuration look like? And do you use facelets as well? Because I'm having the same problem as you just in a facelets view (jsf1.2 + facelets+ richfaces+spring web flow, spring mvc...) with a4j:commandButton...

          Comment


          • #6
            It works

            I did it with with spring webflow + richfaces + myfaces.
            EMAIL ME if interested
            Eric Chavet

            Code:
            <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
            	<modelVersion>4.0.0</modelVersion>
            	<groupId>gov.cg13</groupId>
            	<artifactId>webapp13-libraries</artifactId>
            	<packaging>jar</packaging>
            	<version>2.0</version>
            	<name>webapp13-libraries</name>
            	<properties>
            		<spring.version>3.0.2.RELEASE</spring.version>
            		<spring-security.version>3.0.2.RELEASE</spring-security.version>
            		<spring.tests.integration.version>3.0.0.RC1</spring.tests.integration.version>
            		<hibernate.version>3.5.1-Final</hibernate.version>
            		<myfaces.version>2.0.0</myfaces.version>
            
            		<primefaces.version>1.0.0.RC</primefaces.version>
            
            		<richfaces.version>3.3.3.Final</richfaces.version>
            
            
            		<spring.webflow.version>2.1.0.BUILD-SNAPSHOT</spring.webflow.version>
            
            	</properties>
            
            	<build>
            
            
            	<dependencies>
            		<dependency>
            			<groupId>org.opensymphony.quartz</groupId>
            			<artifactId>quartz</artifactId>
            			<version>1.7.3</version>
            		</dependency>
            		<dependency>
            			<groupId>org.primefaces</groupId>
            			<artifactId>primefaces</artifactId>
            			<version>${primefaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.poi</groupId>
            			<artifactId>poi</artifactId>
            			<version>3.2-FINAL</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.poi</groupId>
            			<artifactId>poi-contrib</artifactId>
            			<version>3.2-FINAL</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.poi</groupId>
            			<artifactId>poi-scratchpad</artifactId>
            			<version>3.2-FINAL</version>
            		</dependency>
            		<dependency>
            			<groupId>com.lowagie</groupId>
            			<artifactId>itext</artifactId>
            			<version>2.1.2</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>cglib</groupId>
            			<artifactId>cglib</artifactId>
            			<version>2.2</version>
            		</dependency>
            		<dependency>
            			<groupId>asm</groupId>
            			<artifactId>asm</artifactId>
            			<version>3.0</version>
            		</dependency>
            		<dependency>
            			<groupId>postgresql</groupId>
            			<artifactId>postgresql</artifactId>
            			<version>8.2-504.jdbc3</version>
            			<scope>runtime</scope>
            		</dependency>
            		<dependency>
            			<groupId>commons-dbcp</groupId>
            			<artifactId>commons-dbcp</artifactId>
            			<version>1.4</version>
            			<scope>runtime</scope>
            		</dependency>
            		<dependency>
            			<groupId>commons-pool</groupId>
            			<artifactId>commons-pool</artifactId>
            			<version>1.5.4</version>
            			<scope>runtime</scope>
            		</dependency>
            		<dependency>
            			<groupId>javax.servlet</groupId>
            			<artifactId>jstl</artifactId>
            			<version>1.1.2</version>
            		</dependency>
            		<dependency>
            			<groupId>org.antlr</groupId>
            			<artifactId>antlr</artifactId>
            			<version>3.0.1</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-ldap</artifactId>
            			<version>1.3.0</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.webflow</groupId>
            			<artifactId>spring-binding</artifactId>
            			<version>${spring.webflow.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.webflow</groupId>
            			<artifactId>spring-js</artifactId>
            			<version>${spring.webflow.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.webflow</groupId>
            			<artifactId>spring-webflow</artifactId>
            			<version>${spring.webflow.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.webflow</groupId>
            			<artifactId>spring-faces</artifactId>
            			<version>${spring.webflow.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-web</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-aop</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-tx</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-webmvc</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-context</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-aspects</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-context-support</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-orm</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework</groupId>
            			<artifactId>spring-beans</artifactId>
            			<version>${spring.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.commons</groupId>
            			<artifactId>digester</artifactId>
            			<version>1.8</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.commons</groupId>
            			<artifactId>beanutils</artifactId>
            			<version>1.7.0</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.commons</groupId>
            			<artifactId>collections</artifactId>
            			<version>3.2</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.commons</groupId>
            			<artifactId>discovery</artifactId>
            			<version>0.4</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.commons</groupId>
            			<artifactId>codec</artifactId>
            			<version>1.3</version>
            		</dependency>
            		<dependency>
            			<groupId>junit</groupId>
            			<artifactId>junit</artifactId>
            			<version>4.6</version>
            			<scope>test</scope>
            		</dependency>
            		<dependency>
            			<groupId>log4j</groupId>
            			<artifactId>log4j</artifactId>
            			<version>1.2.15</version>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-core</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-config</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-openid</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-ldap</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-taglibs</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.springframework.security</groupId>
            			<artifactId>spring-security-web</artifactId>
            			<version>${spring-security.version}</version>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.hibernate</groupId>
            			<artifactId>hibernate-entitymanager</artifactId>
            			<version>${hibernate.version}</version>
            			<type>jar</type>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.hibernate</groupId>
            			<artifactId>hibernate-annotations</artifactId>
            			<version>${hibernate.version}</version>
            			<type>jar</type>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.richfaces.ui</groupId>
            			<artifactId>richfaces-ui</artifactId>
            			<version>${richfaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.richfaces.framework</groupId>
            			<artifactId>richfaces-api</artifactId>
            			<version>${richfaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.richfaces.framework</groupId>
            			<artifactId>richfaces-impl-jsf2</artifactId>
            			<version>${richfaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>com.oracle</groupId>
            			<artifactId>ojdbc14</artifactId>
            			<version>10.2.0.3.0</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.myfaces.core</groupId>
            			<artifactId>myfaces-api</artifactId>
            			<version>${myfaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.apache.myfaces.core</groupId>
            			<artifactId>myfaces-impl</artifactId>
            			<version>${myfaces.version}</version>
            		</dependency>
            		<dependency>
            			<groupId>org.slf4j</groupId>
            			<artifactId>slf4j-log4j12</artifactId>
            			<version>1.5.8</version>
            			<type>jar</type>
            			<scope>compile</scope>
            		</dependency>
            		<dependency>
            			<groupId>org.slf4j</groupId>
            			<artifactId>slf4j-api</artifactId>
            			<version>1.5.8</version>
            			<type>jar</type>
            			<scope>compile</scope>
            		</dependency>
            
            		<dependency>
            			<groupId>com.sun.facelets</groupId>
            			<artifactId>jsf-facelets</artifactId>
            			<version>1.1.15</version>
            			<type>jar</type>
            			<scope>compile</scope>
            		</dependency>
            		 
            
            	</dependencies>
            </project>
            Last edited by echavet; May 14th, 2010, 05:07 PM.

            Comment


            • #7
              Originally posted by xck3001 View Post
              I got it now working by integrating Webflow fully - meaning I added one flow which's view is my JSF+RF page. The AJAX-references are correctly set to the initial URL.
              im also encountering a similar problem, but in my case with form tags.. the action url being set to is the template file and not the url the page was initially accessed. can you explain what you mean by adding another flow? i can't quite get the whole picture..
              thanks a lot

              Comment


              • #8
                Originally posted by echavet View Post
                I did it with with spring webflow + richfaces + myfaces.
                EMAIL ME if interested
                Eric Chavet
                Hi Eric, I'm trying to do the same thing. I've trying to configure it but I'm having many issues. So I'm wondering if it's a good architecture or if I should go to Richfaces + JSF + (simple) Spring Beans.

                Is your app working well with that configuration? Are there any/many problems integration those things? Did you find community response for your problems or you had to find out the solution by yourself? Would you mind posing/email some configuration samples?

                I would really appreciate your help.

                Thanks in advance,

                Gabriel

                Comment


                • #9
                  Did it work?

                  Did it work?

                  I am trying to do the same with primefaces + spring mvc

                  Comment


                  • #10
                    Has anyone got Primefaces work with Spring MVC without using webflows. I'm trying to use the Datatable's sorting/filtering features but does not work....but it works with FLOWS.
                    My application does not require any flows, so just wondering if anyone has got any success.

                    Cheers
                    JP

                    Comment

                    Working...
                    X