Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC 3 + Spring-WS 2 + Spring Security 3 + Tiles Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC 3 + Spring-WS 2 + Spring Security 3 + Tiles

    Hello,

    I'm trying to wire everything to have a web application that can handle Spring MVC and Spring-WS web services, all wrapped under Spring Security and with Tiles as the view technology.

    I've followed this excellent tutorial:

    http://krams915.blogspot.com/2010/12...ing-3-mvc.html

    tried the example code, etc, and it works.

    but when I try to do the same on my project, it is not working. Calls to web services seems to get handled by DispatcherServlet:

    Error:
    Code:
     WARN [org.springframework.web.servlet.PageNotFound] - <N
    o mapping found for HTTP request with URI [/myapp/ws/authentication.wsdl] in DispatcherServlet with name 'myapp'>
    I Know that the xsd is correct and endpoint classes work correctly, because putting them in that tutorial's code acts fine, and I can test them with soapUI.

    I thinks this may be some kind of mapping problem.

    Below you'll find all my config files, important bits in bold; I put everything for the sake of completeness, this is a very tough technology puzzle

    web.xml:
    Code:
    
    <context-param> 
            <param-name>contextConfigLocation</param-name> 
            <param-value>
            	/WEB-INF/applicationContext-jpa.xml
            	/WEB-INF/myapp-security.xml        	     	        
            </param-value> 
    </context-param> 
    <listener> 
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener>
        
    <listener>
        	<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
        
        <servlet> 
            <servlet-name>myapp</servlet-name> 
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
            <init-param>
    	    	<param-name>contextConfigLocation</param-name>
    	    	<param-value>/WEB-INF/myapp-servlet.xml</param-value>
        	</init-param> 
    		<init-param>
    			<param-name>transformWsdlLocations</param-name>
    			<param-value>true</param-value>
    		</init-param>    
        	 
            <load-on-startup>1</load-on-startup> 
        </servlet> 
        
        <servlet-mapping> 
            <servlet-name>myapp</servlet-name> 
            <url-pattern>/*</url-pattern>        
        </servlet-mapping>	
      
        <filter>
    	  <filter-name>springSecurityFilterChain</filter-name>
    	  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    	</filter>
    	
    	<filter-mapping>
    	  <filter-name>springSecurityFilterChain</filter-name>
    	  <url-pattern>/*</url-pattern>
    	</filter-mapping>
    </web-app>
    applicationContext-jpa.xml:
    Code:
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        ...
     />
    
    <!-- JPA EntityManagerFactory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    	    ...
    </bean>
    
    
    	<!-- Transaction Config -->
    	<bean id="transactionManager" 
          		class="org.springframework.orm.jpa.JpaTransactionManager" 
          		p:entityManagerFactory-ref="entityManagerFactory"
          		p:dataSource-ref="dataSource"/> 
     
    	<tx:annotation-driven/><!--  mode="aspectj" transaction-manager="transactionManager"/> --> 
    	
    	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    	
      	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    
    	<!-- Contains the configuration to integrate Spring MVC and Spring WS using the
    	DispatcherServlet and MessageDispatcher -->
    	<import resource = "mvc-ws-integration.xml" />
    
    	<!-- Contains the Spring WS specific configuration -->
    	<import resource = "spring-ws.xml" />
    
    </beans>
    mvc-ws-integration.xml (taken from the tutorial):
    Code:
    	<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
    
    	<bean class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter"
    			p:messageFactory-ref="messageFactory"/>
    
    	<bean class="org.springframework.ws.transport.http.WsdlDefinitionHandlerAdapter"/>
    	
    	<bean id="messageDispatcher" class="org.springframework.ws.server.MessageDispatcher">
    		 	<property name="endpointAdapters">
    		 		<list>
    					<ref bean="defaultMethodEndpointAdapter"/>
    				</list>	
    			</property>
    	 </bean>
    	 
    	 <!--  See reference at the beginning of this document -->
    	 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
    			<value>
    				/ws=messageDispatcher
    				/ws/authentication.wsdl=authentication
    			</value>
    		</property> 
        </bean>
        
        <!--  See reference at the beginning of this document -->
       <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
       
    </beans>
    spring-ws.xml (taken from the tutorial):
    Code:
    	 <sws:annotation-driven />
    	 
    	 <sws:interceptors>
    	 	    <bean id="validatingInterceptor"  class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"
    				        p:schema="/WEB-INF/xsd/authentication.xsd"
    				        p:validateRequest="true"
    				        p:validateResponse="true"/>
    
    		    <bean id="loggingInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
    	 </sws:interceptors>
    
        <sws:dynamic-wsdl id="authentication"                                                           
    	    portTypeName="AuthenticationRequest"                                                         
    	    locationUri="/"                                                       
    	    targetNamespace="http://mycompany.org/myapp/schemas">                               
    	  <sws:xsd location="/WEB-INF/xsd/authentication.xsd"/>                                                  
    	</sws:dynamic-wsdl>
    
    	<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"
        	p:mappingLocation="/WEB-INF/castor-mapping.xml" />
     
     	
    	<bean id="marshallingPayloadMethodProcessor" class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
    		<constructor-arg ref="castorMarshaller"/>
    		<constructor-arg ref="castorMarshaller"/>
    	</bean>
    	
    	<bean id="defaultMethodEndpointAdapter" class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
    		<property name="methodArgumentResolvers">
    			<list>
    				<ref bean="marshallingPayloadMethodProcessor"/>
    			</list>	
    		</property>
    		<property name="methodReturnValueHandlers">
    			<list>
    				<ref bean="marshallingPayloadMethodProcessor"/>
    			</list>
    		</property>
    	</bean>
    </beans>
    myapp-security.xml:
    Code:
      <http auto-config="true" use-expressions="true">
      	<intercept-url pattern="/resources/**" access="permitAll" />
      	
      	<!-- Allow everyone access to web services endpoints -->
      	<intercept-url pattern="/ws/**" access="permitAll" />
      	
      	<!-- Force login through SSL (https) -->
      	<intercept-url pattern="/login" access="permitAll" requires-channel="https" />
    	
        <intercept-url pattern="/*" access="hasRole('ROLE_USER')" requires-channel="https"/>
    
        <form-login login-page="/login"
        			authentication-failure-url = "/login/?login_error=1"/>
    
        <remember-me key="myapp-rTy4444454564546546l5tjhdfjhdrKzZ"/>
     
        <logout invalidate-session="true" logout-success-url="/login" logout-url="/logout"/>
     
         <session-management>
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>
         
      </http>
      
      <authentication-manager alias="authenticationManager">
      	<authentication-provider  user-service-ref="jdbcUserService"  >
      	</authentication-provider>
      </authentication-manager>
    
        
    <beans:bean id="jdbcUserService" 
    ...
    </beans:bean>
       
    </beans:beans>
    authentication.xsd:
    Code:
    <?xml version="1.0"  encoding="UTF-8"?>
    <schema 
    		xmlns="http://www.w3.org/2001/XMLSchema" 
    		elementFormDefault="qualified" 
    		attributeFormDefault="qualified"
            targetNamespace="http://mycompany.org/myapp/schemas"
            xmlns:tns="http://mycompany.org/myapp/schemas">
            
        <element name="username" tns:maxOccurs="1" tns:minOccurs="1">
            <simpleType>
                <restriction base="string">
                    <pattern value="([A-Z]|[a-z]|\s|\.)+"/>
                    <minLength value="3"/>
                </restriction>
            </simpleType>
        </element>
        
        <element name="password" tns:maxOccurs="1" tns:minOccurs="1">
            <simpleType>
                <restriction base="string">
                    <pattern value="([A-Z]|[a-z]|\s|\.)+"/>
                    <minLength value="3"/>
                </restriction>
            </simpleType>
        </element>
            
        <element name="authenticationRequest" tns:maxOccurs="1" tns:minOccurs="1">
    		<complexType >
    			<sequence>
    				<element ref="tns:username" />
    				<element ref="tns:password" />				
    			</sequence>
    		</complexType>
        </element>
    </schema>
    for the brave soul that checks these files, if you find some file missing i can post more info.

    Thanks,

    Nacho

  • #2
    Forgot to mention:

    Before adding the Spring-WS parts, my web app was working correctly (controllers, tiles views, etc).

    Now it wont recognize any url:

    WARN [org.springframework.web.servlet.PageNotFound] - <N
    o mapping found for HTTP request with URI [/myapp/WEB-INF/jsp/layout.jsp] in
    DispatcherServlet with name 'myapp'>

    layout.jsp is the base layout for all tiles.
    Last edited by npintos; Feb 1st, 2011, 11:43 AM.

    Comment


    • #3
      Where did the name fitrehab for the DispatcherServlet come from in the above post?

      Comment


      • #4
        oops, sorry, it should have said 'myapp' instead of that.

        About my second post, I managed to solve it. None of my views were resolving because instead of:

        Code:
        <servlet-mapping> 
                <servlet-name>myapp</servlet-name> 
                <url-pattern>/*</url-pattern>        
        </servlet-mapping>
        Should be:

        Code:
        <servlet-mapping> 
                <servlet-name>myapp</servlet-name> 
                <url-pattern>/</url-pattern>        
        </servlet-mapping>
        (without the asterisk).

        Now my MVC app works again. But the main problem is that the web services part is still not resolving, and handed to the DispatcherServlet despite the SimpleUrlHandlerMapping in mvc-ws-integration.xml (see files above)

        Any hint, no matter how tiny?

        Cheers,

        Nacho

        Comment


        • #5
          I'm a bit new to Spring myself, so I'm not sure if this is helpful. Is there a chance that it might be mandatory that the file should be named applicationContext.xml and not applicationContext-jpa.xml. Because the tutorial link you provided says: "By convention, we must declare an applicationContext.xml as well."

          Comment


          • #6
            Hi vithun,

            I don't think that's the problem. If you use the standard name (applicationContext.xml), you don't have to declare it on web.xml. If you use a custom name (like me), you specify it in the web.xml file.

            The MVC part of my app works prefect (i can navigate, load forms, save data in the database...), is just the integration with Spring Web Services that is troubling now, I can't see the WSDL published and the EndPoint is not called.

            Anyway, thanks for your reply!

            Nacho

            Comment


            • #7
              In mvc-ws-integration.xml, try changing it to /myapp/ws=messageDispatcher and /myapp/ws/authentication.wsdl=authentication

              Comment


              • #8
                I already did, but no luck.

                It feels like the SimpleUrlHandlerMapping is never used. I guess it mkay have something to do with the url mapping in web.xml...

                Also, I forgot to mention: Spring Security is active, and it requires https for every request.
                I configured https on Tomcat on port 8443.
                http://localhost:8443/myapp/ws/authentication.wsdl is not working
                http://localhost:8080/myapp/ws/authentication.wsdl is also not working

                I'm sure it has to be something really evident/easy/stupid mistake thingy...

                Comment


                • #9
                  What are the URLs that are working? Could you give a URL from the MVC part that is working fine.

                  Comment


                  • #10
                    Ok. Even I'm trying to think silly mistakes. Can it be because you missed an 's' in the link: https://localhost:8443/myapp/ws/authentication.wsdl and its not an https request.

                    Comment


                    • #11
                      My mistake again, I actually tried with that 's' in the URL.

                      The URLs that work are things like:

                      https://localhost:8443/myapp (for login)
                      https://localhost:8443/home
                      https://localhost:8443/customer/new

                      etc.

                      I'm expecting a huge facepalm when I find the error

                      Comment


                      • #12
                        Just see if the solution to this problem works for you:
                        http://forum.springsource.org/showthread.php?t=10880

                        (Setting alwaysUseFullPath property to true in the SimpleUrlHandlerMapping bean).

                        Comment


                        • #13
                          @npintos, thanks for following the tutorial I wrote

                          Can you try disabling your Spring Security config? (Just comment it out from the web.xml).

                          Also when I combine Spring Security, WS, and MVC, the url-mapping I use for Security is /* but for the MVC and WS I use a child mapping like /web/*

                          In fact, when I just use Security and MVC (no WS) I encounter issues with Tiles when both are mapped to /*. Maybe it's conflicting with something. I still haven't figured out the exact reason but I was able to solve it by mapping the MVC/WS to a child path

                          Comment


                          • #14
                            Vithun,

                            Thanks for the suggestion! but it did not work

                            skram,

                            No, thanks to you for such a thorough tutorial!

                            If I understood well, you suggested:

                            web.xml: a child mapping for the servlet, root mapping for security
                            Code:
                            <servlet-mapping> 
                                <servlet-name>myapp</servlet-name> 
                                <url-pattern>/hs/*</url-pattern>           
                            </servlet-mapping>
                            
                            <filter-mapping>
                              <filter-name>springSecurityFilterChain</filter-name>
                              <url-pattern>/*</url-pattern>
                            </filter-mapping>
                            security.xml: left untouched ()excerpt below
                            Code:
                            <http auto-config="true" use-expressions="true">
                              	<!-- Allow everyone access to images, javascript and stylesheets -->
                              	<intercept-url pattern="/resources/**" access="permitAll" />
                            
                              	<intercept-url pattern="/ws" access="permitAll" />
                              	
                              	<!--  Allow everyone access to web services endpoints --> 
                              	<intercept-url pattern="/ws/**" access="permitAll" />
                              	
                              	<!-- Force login through SSL (https) -->
                              	<intercept-url pattern="/login" access="permitAll" requires-channel="https" />
                              	 
                              	<!-- Force every controller to use SSL (https) -->
                                <intercept-url pattern="/*" access="hasRole('ROLE_USER')" requires-channel="https"/>
                            myapp-servlet.xml (left untouched, excerpt)
                            Code:
                            <!-- Maps '/' requests to the 'home' view -->
                            <mvc:view-controller path="/" view-name="home"/>
                            <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
                            <mvc:resources mapping="/resources/**" location="/resources/" />
                            <!-- Package where the controllers reside -->
                            <context:component-scan base-package="org.mycompany.myapp" /> 
                            <!-- Views resolver: Tiles  -->
                            <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
                            <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
                            </bean>
                            <!-- Tiles Configuration and Definitions -->
                            <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
                            <property name="definitions">
                            	<list>
                            		<value>/WEB-INF/definitions/tiles-defs.xml</value>
                            	</list>
                            </property>
                            </bean>
                            
                            <!-- Interceptor defined elsewhere -->
                            <bean id="handlerMapping"
                            class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
                                <property name="interceptors">
                                    <ref bean="localeChangeInterceptor" />
                                </property>
                            </bean>
                            And mvc-ws-integration.xml (left untouched):
                            Code:
                            <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                                    <property name="mappings">
                            			<value>
                            				/ws=messageDispatcher
                            				/ws/authentication.wsdl=authentication
                            			</value>
                            		</property> 
                            </bean>
                            Even with this modifications (well, I only changed the mappings in web.xml), the WS part is still not working. I can access my webapp with https://localhost:8443/myapp/hs/, but I keep getting a:
                            Code:
                            WARN [org.springframework.web.servlet.PageNotFound] - <N
                            o mapping found for HTTP request with URI [/myapp/hs/ws/authentication.wsdl]
                            in DispatcherServlet with name 'myapp'>
                            Do you think any of the configuration lines in bold is clashing with another?

                            I've spent the past two days with trial and error, I never expected this configuration to be so troublesome (and so undocumented)

                            Thanks both for your help!

                            Comment


                            • #15
                              Oh, forgot to mention: disabling security in web.xml does not help either

                              Comment

                              Working...
                              X