文章目录

  • 1、webservice 简介
  • 2、CXF 框架(xml调用)
  • 2.1、创建服务端项目,发布xml
  • 2.2、创建客户端项目,解析xml
  • 3、调取别人发布的webservice 思路
  • 4、区别版本


1、webservice 简介

常见的web服务:

  • 天气信息
  • 手机淘宝、京东
  • 股票查询

这些信息都是公开的,服务商家通常会提供一个xml的web信息接口,供开发者调用。

webservice是可以跨语言传送数据的。

Java 中共有三种WebService 规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。

  • JAXM&SAAJ : 基于javax.messaging.*包 (需要手动下载这个包)
  • JAX-WS(JAX-RPC):基于javax.xml.ws.*包(原生java支持)
  • JAX-RS : 基于java.ws.rs.*包(restful风格)

java WCF服务 java webservice服务端_java


我们常用JAX-WS 规范、JAX-RS规范获取数据。

使用JAX-WS 规范涉及的名词:

SOAP协议 = HTTP + XML 数据。
wsdl :是一种 XML 文档,描述某个 Web service。
UDDI : 就是一个目录,这个目录中存放一些关于web服务的信息。

2、CXF 框架(xml调用)

2.1、创建服务端项目,发布xml

先创建一个空项目,再新建一个maven子模块

java WCF服务 java webservice服务端_java WCF服务_02


填写一下子模块的基本信息,完事下一步就可以

java WCF服务 java webservice服务端_java_03


接下添加依赖

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

java WCF服务 java webservice服务端_xml_04

创建一个service:HelloService.java

import javax.jws.WebService;

/**
 * 对外发布服务的接口
 * **/
@WebService
public interface HelloService {
    // 对外发布服务的接口的方法
    public String sayHello(String name);
}

HelloServiceImpl.java

public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        return name+",hello haha";
    }
}

创建Server.java发布项目

import com.haha.service.HelloServiceImpl;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

/**
 * 发布项目
 * **/
public class Server {
    public static void main(String[] args) {

        // 发布服务的工厂
        JaxWsServerFactoryBean f = new JaxWsServerFactoryBean();
        // 设置服务地址
        f.setAddress("http://localhost:8000/ws/hello");
        // 设置服务类
        f.setServiceBean(new HelloServiceImpl());
        //发布服务
        f.create();

        System.out.println("发布成功,端口8000。。。");
    }
}

java WCF服务 java webservice服务端_java WCF服务_05


浏览器访问:http://localhost:8000/ws/hello

java WCF服务 java webservice服务端_apache_06


访问连接后面加个?wsdl

java WCF服务 java webservice服务端_xml_07

2.2、创建客户端项目,解析xml

新建一个模块

java WCF服务 java webservice服务端_java_08


加入依赖

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

然后创建一个与服务端同名、同包路径的接口
HelloService.java

import javax.jws.WebService;

/**
 * 对外发布服务的接口
 * **/
@WebService
public interface HelloService {
    // 对外发布服务的接口的方法
    public String sayHello(String name);
}

java WCF服务 java webservice服务端_apache_09


然后获取数据Client.java

import com.haha.service.HelloService;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class Client {
    public static void main(String[] args) {
        JaxWsProxyFactoryBean f = new JaxWsProxyFactoryBean();
        f.setAddress("http://localhost:8000/ws/hello");
        f.setServiceClass(HelloService.class);
        HelloService helloService = f.create(HelloService.class);
        System.out.println(helloService.getClass());
        String content = helloService.sayHello("Jet");
        System.out.println(content);

    }
}

运行

java WCF服务 java webservice服务端_java_10

3、调取别人发布的webservice 思路

使用之前必看:
调用别人的wsdl文件要注意他采用的什么版本,不同的版本采用的jdk版本不同
区别版本请看标题 “4、区别版本”

第一步:使用wsimport生成java接口

wsimport是jdk自带的工具

java WCF服务 java webservice服务端_xml_11


wsimport参数:


-keep:是否生成java源文件


-d:指定.class文件的输出目录


-s:指定.java文件的输出目录


-p:定义生成类的包名,不定义的话有默认包名


-verbose:在控制台显示输出信息


-b:指定jaxws/jaxb绑定文件或额外的schemas


-extension:使用扩展来支持SOAP1.2

在cmd输入指令:wsimport -keep -s D:\Workspaces -p com.cn.phone -verbose 接口url

java WCF服务 java webservice服务端_java_12

注意D:\Workspaces需要提前创建好
示例接口地址:http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl

下面是生成好的内容

java WCF服务 java webservice服务端_java WCF服务_13

第二步:新建一个maven项目,导入cxf框架的依赖

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

第三步:创建接口对应的包名(一定要和接口文件里一样),然后将生成的接口放进去

java WCF服务 java webservice服务端_apache_14


第四步:创建客户端类

import com.cn.phone.ArrayOfString;
import com.cn.phone.IpAddressSearchWebServiceSoap;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import java.rmi.RemoteException;

public class Client {
    public static void main(String[] args) throws RemoteException {
        JaxWsProxyFactoryBean f = new JaxWsProxyFactoryBean();
        f.setAddress("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx");

        f.setServiceClass(IpAddressSearchWebServiceSoap.class);
        IpAddressSearchWebServiceSoap h =f.create(IpAddressSearchWebServiceSoap.class);

//        System.out.println(helloService.getClass());
        //传参数
//        String content = helloService.sayHello("Jet");

        ArrayOfString content = h.getCountryCityByIp("183.69.220.193");
        System.out.println(content.getString());

    }
}

java WCF服务 java webservice服务端_java_15


在执行wsimport中,如果出现undefined simple or complex type 'soapenc:Array’这样的错误,可能是由于wsdl文档版本过低造成的,可以按照如下例修改

这个问题是版本不同造成的,如下操作不一定能解决问题,建议更换jdk版本

修改前的文档

<s:schema targetNamespace="http://tempuri.org/AbstractTypes">
      <s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
       <s:complexType name="ArrayOfString">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
        </s:sequence>
      </s:complexType>
	  <s:complexType name="StringArray">
        <s:complexContent mixed="false">
          <s:restriction base="soapenc:Array">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="unbounded" name="String" type="s:string" />
            </s:sequence>
          </s:restriction>
        </s:complexContent>
      </s:complexType>

修改后的文档

<s:schema targetNamespace="http://tempuri.org/AbstractTypes">
      <s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
	  <s:complexType name="ArrayOfString">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
        </s:sequence>
      </s:complexType>
    </s:schema>

4、区别版本

SOAP协议到目前有两个版本:SOAP1.1和SOAP1.2
区别:

  • 他们的WSDL文件的命名空间是不一样的。
  • SOAP1.1存在SOAPAction的请求头、.SOAP1.2没有SOAPAction的请求头。
  • 在CXF中两种协议请求的方式也不一样。SOAP1.1为content-Type:text/xm;charset=UTF-8、SOAP1.2为content-Type:application/soap+xml;charset=UTF-8。
  • SOAP1.1 对应jdk1.6、SOAP1.2 对应jdk1.8
  • cxf 两个版本都支持

SOAP1.1 的WSDL文件命名空间:

xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/ “

SOAP1.2 的WSDL文件命名空间:

xmlns:soap="http://www.w3.org/2003/05/soap-envelope“

在定义Service部分差别如下:
Soap1.1是以:soap:address定义。
Soap1.2是以: soap12:address定义。

jdk1.6不支持Soap1.2形式的访问。