使用 Apache cxf 实现 WebService 客户端

ws-client-demo

客户端调用远程服务

http://localhost:8280/services/HelloWorld?wsdl

spring + cfx 配置

maven

添加依赖包

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

wsdl2java

把 HelloWorld.wsdl 下载到 resources 当中

使用 maven 插件 cxf-codegen-plugin 生成代码

  <plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>3.2.2</version>
    <executions>
      <execution>
        <id>generate-sources</id>
        <phase>generate-sources</phase>
        <configuration>
          <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
          <wsdlOptions>
            <wsdlOption>
              <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>
            </wsdlOption>
          </wsdlOptions>
        </configuration>
        <goals>
          <goal>wsdl2java</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

maven compile 任务完成之后在target\generated\cxf\com\example\demo\ws 下会有很多文件

    CurrentDate.java
    CurrentDateResponse.java
    HelloWorld.java
    HelloWorldImplService.java
    ObjectFactory.java
    package-info.java
    SayHi.java
    SayHiResponse.java

调用 WebService

使用 spring

把 HelloWorld.java 复制到 srcmainjavacomexampledemows 目录下

同时 HelloWorld.java 里面 @XmlSeeAlso({ObjectFactory.class})这行代码删掉

<?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:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:client id="helloClient"
                  serviceClass="com.example.demo.ws.service.HelloWorld"
                  address="http://localhost:8280/services/HelloWorld" />
</beans>
package com.example.demo;

import com.example.demo.ws.service.HelloWorld;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.xml.datatype.XMLGregorianCalendar;

public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld client = (HelloWorld) context.getBean("helloClient");

        String resp1 = client.sayHi("小明");
        System.out.println(resp1);
        XMLGregorianCalendar resp2 = client.currentDate();
        System.out.println(resp2.toString());
    }
}
不使用 spring
package com.example.demo;

import com.example.demo.ws.service.HelloWorld;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;

public class WithoutSpring {
    public static void main(String[] args) throws MalformedURLException {
        URL wsdlURL = new URL("http://localhost:8280/services/HelloWorld?wsdl");
        QName SERVICE_NAME = new QName("http://service.ws.demo.example.com/", "HelloWorldImplService");
        Service service = Service.create(wsdlURL, SERVICE_NAME);
        HelloWorld client = service.getPort(HelloWorld.class);
        String result = client.sayHi("小红");
        System.out.println(result);
    }
}

可以直接运行的demo

GitHub https://github.com/openmartin...

其他配置

demo 中是比较简单的情况,但是实际的情况会更复杂,下面介绍一下常用的配置

SSL Certificate and Proxy

参考 https://cxf.apache.org/docs/c...

在 applicationContext.xml 可以为web service client 配置proxy 和 ssl cert,完全不用写代码。

ssl 证书有两种形式 pkcs12、jks, 指定路径有三种形式 url、file、resource

<?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:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://cxf.apache.org/configuration/security
       http://cxf.apache.org/schemas/configuration/security.xsd
       http://cxf.apache.org/transports/http/configuration
       http://cxf.apache.org/schemas/configuration/http-conf.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">

    <http:conduit name="{http://service.ws.demo.example.com/}HelloWorldImplService.http-conduit">

        <http:tlsClientParameters>
            <sec:keyManagers keyPassword="PASSWORD">
                <sec:keyStore type="pkcs12" password="PASSWORD"
                              resource="classpath:DLWSCert.p12"/>
            </sec:keyManagers>
            <sec:trustManagers>
            <sec:keyStore type="JKS" password="PASSWORD"
                      file="my/file/dir/Truststore.jks"/>
            </sec:trustManagers>
            <sec:cipherSuitesFilter>
                <!-- these filters ensure that a ciphersuite with
                     export-suitable or null encryption is used,
                     but exclude anonymous Diffie-Hellman key change as
                     this is vulnerable to man-in-the-middle attacks -->
                <sec:include>.*_EXPORT_.*</sec:include>
                <sec:include>.*_EXPORT1024_.*</sec:include>
                <sec:include>.*_WITH_DES_.*</sec:include>
                <sec:include>.*_WITH_AES_.*</sec:include>
                <sec:include>.*_WITH_NULL_.*</sec:include>
                <sec:exclude>.*_DH_anon_.*</sec:exclude>
            </sec:cipherSuitesFilter>
        </http:tlsClientParameters>
        <http:client AutoRedirect="true" Connection="Keep-Alive" ProxyServer="192.168.1.100" ProxyServerPort="8080"/>

    </http:conduit>
    
    <jaxws:client id="helloClient" serviceClass="com.example.demo.ws.service.HelloWorld"
    address="https://localhost:8280/services/HelloWorld"/>

</beans>

cxf-codegen-plugin

cxf 的 maven 插件可以指定参数来解决一下常见的问题(<extraargs>下的<extraarg>可以选择所需的wsdl2java命令参数使用)

参考 http://cxf.apache.org/docs/ws...

  • 添加-autoNameResolution 解决wsdl中命名冲突
  • 添加-p packagename 指定自动生成的包名
      <plugin>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-codegen-plugin</artifactId>
        <version>3.2.2</version>
        <executions>
          <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
              <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
              <wsdlOptions>
                <wsdlOption>
                  <wsdl>${basedir}/src/main/resources/HelloWorld.wsdl</wsdl>
                  <extraargs>
                    <extraarg>-autoNameResolution</extraarg>
                    <extraarg>-verbose</extraarg>
                    <extraarg>-p</extraarg>
                    <extraarg>com.example.demo.ws</extraarg>
                  </extraargs>
                </wsdlOption>
              </wsdlOptions>
            </configuration>
            <goals>
              <goal>wsdl2java</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值