Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Apache cxf with spring mvc in a single application with shared services

I'm currently working a project which based on spring MVC, it's just a standard project using spring MVC template. so I have web.xml and servlet-context.xml.

I'm working on adding Apache cxf web services into this project, and meet some problems on sharing services with existing Spring MVC.

My initial approach was trying to get web services working, so here is my web.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets 
        and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml
        /WEB-INF/spring/jaxwsServlet/jaxwsServlet-context.xml
        </param-value>
    </context-param>




    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Process web service requests -->
    <servlet>
        <servlet-name>jaxws</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jaxws</servlet-name>
        <url-pattern>/industryAspectWS</url-pattern>
    </servlet-mapping>


    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

and my jaxwsServlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ws="http://jax-ws.dev.java.net/spring/core"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://jax-ws.dev.java.net/spring/core
        classpath:spring-jax-ws-core.xsd
        http://jax-ws.dev.java.net/spring/servlet
        classpath:spring-jax-ws-servlet.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>   
    <wss:binding url="/industryAspectWS">
        <wss:service>
            <ws:service bean="#industryAspectWS"/>
        </wss:service>
    </wss:binding>

    <!-- Web service methods -->
    <bean id="industryAspectWS" class="com.example.ws.IndustryAspectWS"></bean>

    <context:component-scan base-package="com.example" />

    <beans:import resource="../HibernateTransaction.xml" />

    <beans:import resource="../JaxbMarshaller.xml" />

</beans>

I copied the context:component-scan beans:import sections from servlet-context.xml

This configuration works okay since I was able to boot up the server, and call Web services and also access servlet and jsp. However, I notice that since I quoted the hibernateTransaction.xml in both context xml files, there are two session factories.

I want to share all services (such as hibernate) between Apache cxf and Spring MVC controllers, so I tried to put settings in root-context.xml, it didn't work. I also tried to search this online, but didn't find any complete examples on shared services. Is it possible that we can put a setting to share services among the two?

=================================================

I had experimented some settings after I post this, and figured that if I put the lines of

<context:component-scan base-package="com.example" />

and

<tx:annotation-driven transaction-manager="txManagerExample" />

in both servlet-context.xml and jaxwsServlet-context.xml, it will work just fine. all other settings can stay in the shared root-context.xml

like image 869
rzch Avatar asked Aug 29 '12 03:08

rzch


1 Answers

WSSpringServlet is not CXF. It is Metro. I would recommend using CXF. In that case you will have a CXFServlet but then you would set up CXF in your main Spring context (the one created by ContextLoaderListener.

It would work as follows: your main context would have all of the shared beans including CXF. Your Servlet context would have just your controllers. Since the servlet context is a child of the main context your controllers would also have access to everything in the main context.

See the Embedding CXF inside of Spring page, the CXF Servlet Transport Page, and my answer to this question about sharing beans between servlet context and main context.

like image 176
sourcedelica Avatar answered Sep 29 '22 02:09

sourcedelica