Spring MVC + CXF实现webservice接口

本来都是WebAPI/RestfulAPI接口对外提供接口的,突然有个需求要提供WebService接口,本想着Spring和CXF这么成熟的两个产品,这么的也整不出什么幺蛾子来啊。

结果还真是出了几个幺蛾子。把解决方案贴出来,希望能帮助有需求的小伙伴少走弯路。

解决方案的软件版本(OpenJDK10,Spring MVC 5,CXF 3)

1.OpenJDK中WebService的注解不见了

解决方案:追加第三方依赖包,注意type是pom

        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-ri</artifactId>
            <version>2.3.2</version>
            <type>pom</type>
        </dependency>

    <dependency>
        <groupId>com.sun.activation</groupId>
        <artifactId>javax.activation</artifactId>
        <version>1.2.0</version>
    </dependency>

2.WebService配置文件,网上搜出来的版本五花八门,不知道哪种是对的

解决方案:

spring-webservice.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <!-- 自动扫描webService -->
    <context:component-scan base-package="com.xxx.webservice.impl" />
    <!-- 定义webservice的发布接口  -->
    <jaxws:endpoint
            implementor="#helloWorld"
            address="/HelloWorld"></jaxws:endpoint>
</beans>

pom.xml

        <!-- webservice -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.1.8</version> 
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.8</version>
        </dependency>

 

3.按照网上的方案,此刻追加了webservice的接口和实现类,

在web.xml里面配置一下映射应该就可以了,

    <servlet>
        <servlet-name>spring-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--定义一个cxf的servlet-->
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>

 

但是,这时候会出现“Can't find the the request for http://localhost:8080/xxx/webservice/HelloWorld's Observer ”找不到实现类

这时候涉及到Spring的两个概念ContextLoaderListener和DispatcherServlet

简单来说ContextLoaderListener是全局Spring的容器,DispatcherServlet是Spring MVC的容器,作用域是不一样的。

我们在SpringMVC中,通常只用到了DispatcherServlet,而CXF目前来看不是使用的这个容器的上下文,所以找不到实现类。

于是我们在web.xml中追加了ContextLoaderListener,并且把所有的Spring相关配置都设置在了他的上下文

    <listener>
        <description>Define spring listener.</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <description>Define applicationContext.xml location.</description>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:spring/spring-*.xml
        </param-value>
    </context-param>
    <servlet>
        <servlet-name>spring-dispatcher</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>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--定义一个cxf的servlet-->
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>

这时候,就可以跑通了,调用到webservice接口了

 

posted @ 2019-03-25 10:41  cxyao  阅读(897)  评论(1编辑  收藏  举报