第一次写文章,所以里边会有些措辞或者描述不清楚的问题,请见谅

首先webservice大家肯定已经耳熟能详了,而且webservice属于比较古老的技术,但一些比较老的公司,由于架构的比较早,而且经历数次迭代,人员更替,旧的技术很难优化,所以难免会遇到对接webservice接口的需求。

对接webservice需要先了解下边的一些知识。

1、XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。
2、Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。
3、WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。
4、UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

接下来就是对接webservice的几种方法

一、生成客户端方式

1、生成webservice客户端,一种可以通过开发工具如eclipse、idea生成,也可以通过工具如apache-cxf通过jdk命令生成

eclipse生成:

(1)、创建一个java project项目

java 使用soap通讯 java soap wsdl_httpclient

(2)、在项目的src文件夹右键-->new-->other-->web service client

java 使用soap通讯 java soap wsdl_webservice接口对接_02

(3)、输入webservice的接口地址,选择finish

java 使用soap通讯 java soap wsdl_webservice接口对接_03

apache-cxf生成客户端:

(1)、安装apache-cxf,我这里安装的是apache-cxf-2.7.7,需要配置环境变量,且jdk1.7,1.6都可以,但不能为1.8,这很重要,否则会报错,安装过程及配置环境变量就不详说了,可自行搜索安装

java 使用soap通讯 java soap wsdl_webservice接口对接_04

注:cxf生成的客户端,是需要cxf的jar包的,可以自行下载,或者找我要

(2)、cmd运行命令

wsdl2java -encoding utf-8  -p 包名 -d 保存路径 webservice接口wsdl地址

注:-encoding utf-8是对生成客户端编码进行设置,可自行匹配项目编码进行调整,去掉的话默认gbk

2、客户端代码编写

 

如果生成了客户端,首先需要先了解是否有接口的实现类可以供我们直接调用,如果无的话,可以使用JaxWsDynamicClientFactory或者JaxWsProxyFactoryBean来通过接口service创建接口实现类对象,

JaxWsProxyFactoryBean方式:

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("***********?wsdl");
factory.setServiceClass(UISearchHotelService.class);//接口类
UISearchHotelService service = (UISearchHotelService) factory.create();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);
// 这个用户即服务器端配置的用户名
outProps.put(WSHandlerConstants.USER, "client"); //随便填 ,但是不可不填
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
        
Client client = ClientProxy.getClient(service);
Endpoint cxfEndpoint = client.getEndpoint();
cxfEndpoint.getEndpointInfo().setProperty("set-jaxb-validation-event-handler", "false");
cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());
cxfEndpoint.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));

JaxWsDynamicClientFactory方式:

JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();  
Client client = clientFactory.createClient("*****?wsdl");  
Object[] result = client.invoke("sayHello", "KEVIN");

invoke方法的第一个参数是方法名称,第二个是参数名称

二、不生成客户端,直接通过httpclient实现

不得不说,这种方法一般都是优先考虑的,因为客户端会强加代码,而且还需要后期维护,比较繁琐,相比较而言,httpclient是最简便的方法

String soapRequestData = "这块是xml的头,体以及参数的拼接";
System.out.println(soapRequestData);
PostMethod postMethod = new PostMethod("********?wsdl");
// 然后把Soap请求数据添加到PostMethod中
byte[] b;
try {
	b = soapRequestData.getBytes("utf-8");
	InputStream is = new ByteArrayInputStream(b, 0, b.length);
	RequestEntity re = new InputStreamRequestEntity(is, b.length,"application/soap+xml; charset=utf-8");
	postMethod.setRequestEntity(re);
	// 最后生成一个HttpClient对象,并发出postMethod请求
	HttpClient httpClient = new HttpClient();
	int statusCode = httpClient.executeMethod(postMethod);
	if(statusCode == 200) {
		System.out.println("调用成功!");
		String soapResponseData = postMethod.getResponseBodyAsString();
		System.out.println(soapResponseData);
	} else {
		System.out.println("调用失败!错误码:" + statusCode);
	}
} catch (UnsupportedEncodingException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} catch (HttpException e) {
    // TODO Auto-generated catch block
	e.printStackTrace();
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}