spring整合cxf,轻松编写webService客户端、服务端

WebService是一种跨编程语言、跨操作系统平台的远程调用技术,广泛应用在实际开发,接口实现,系统集成。

服务端

  1. List item

添加maven依赖
项目中除了spring相关的依赖以外,还需添加下面两个依赖。

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>3.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>3.3.5</version>
      <scope>compile</scope>
    </dependency>
  1. 配置web.xml

除了常规的spring相关配置,这里需要添加cxfServlet的配置。

<!--  1.cxfServlet配置-->
  <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>
<!--  2.配置spring容器-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
<!--    3.监听器-->
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  1. 编写webService接口以及实现类
    IHelloService 接口类
    接口需要标注@webservice注解
@WebService
public interface IHelloService {

    /**
     *     对外发布服务接口的方法
     *      @param name
     */
    public String welcome(String name);
}

HelloServiceImpl 接口实现类

public class HelloServiceImpl implements IHelloService {
    @Override
    public String welcome(String name) {
        return "welcome to webService "+name;
    }
}

  1. 配置applicationContext.xml
    在命名空间中需要添加cxf相关的xsd,然后配置服务对应的信息,包括服务地址,服务类等
<?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:context="http://www.springframework.org/schema/context"
       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd">
    <cxf:server address="/hello">
        <jaxws:serviceBean>
            <bean class="service.impl.HelloServiceImpl"></bean>
        </jaxws:serviceBean>
    </cxf:server>
</beans>
  1. 启动web服务,测试
    服务启动成功后,我们可以在浏览器中访问:http://localhost:8081/webservice/hello?wsdl其中,http://localhost:8081为我们服务器访问入口,/webservice为我们在web.xml配置文件中配置的cxfServlet对应的servlet-mapping/hello为该服务访问的address地址,最后还需要加上?wsdl访问wsdl说明书。
    下图为ie浏览器的显示效果,我测试的火狐浏览器则显示空白,对应f12的内容与下图内容一致。
    spring整合cxf,轻松编写webService客户端、服务端客户端

  2. 添加cxf相关依赖

  3. 导入服务接口类型对应的类
    这里,我们需要将服务端的IHelloService和HelloServiceImpl添加到客户端代码中。另外,不管是客户端还是服务端,IHelloService接口都是需要标注@webService注解的。

  4. 编写客户端的applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd"
    <jaxws:client id="helloService" serviceClass="service.impl.HelloServiceImpl" address="http://localhost:8081/webservice/hello"></jaxws:client>
</beans>
  1. 编写单元测试
    这里使用到了spring的单元测试,所以,不光要导入junit的依赖,还需要spring-test的依赖。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {

    //注入对象
    @Resource
    private HelloServiceImpl helloService;
    @Test
    public void doClientRemote(){
        System.out.println(helloService);
        String content = helloService.welcome("Elaine");
        System.out.println(content);
    }

}
  1. 查看输出结果
org.apache.cxf.jaxws.JaxWsClientProxy@45905bff
welcome to webService Elaine

可以发现,我们获取的HelloServiceImpl 对象是代理对象,因为事先了相关接口,自然是通过jdk动态代理实现的。
查看服务端输出时,有这样一个警告

org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://impl.service/}welcome found.   Expected {http://service/}welcome.

很好理解,我们在单元测试获取的代理对象类型为实现类,cxf更希望我们直接用接口类型。替换为:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {

    //注入对象
    @Resource
    private IHelloService helloService;
    @Test
    public void doClientRemote(){
        System.out.println(helloService);
        String content = helloService.welcome("Elaine");
        System.out.println(content);
    }

}

重新测试,无警告,无报错。

上一篇:第一个springBoot程序及执行


下一篇:新手小白也能成码农之Java 实例 - 数组输出