背景
最近要对接HIS系统,对方提供的接口是webservice的(有点古老),对方是webservice的提供方,提供了wsdl文件,我方需要根据wsdl文件生成java代码,intellij idea生成webservice客户端代码支持的不是很好,研究得知,可通过wsimport命令来生成,
- wsimport 根据wsdl文件生成java代码;
- wsgen 根据源码生成wsdl描述文件,具体来说就是根据endpoint implementation class生成必要的文件,包括但不限于wsdl文件。
这两个命令在%JAVA_HOME%\bin
下。
根据wsdl生成java代码
wsimport -encoding utf8 -p 包名 -wsdllocation http://somedomain/some/path/some.wsdl wsdl文件路径
- -encoding,指定生成的java文件的编码
- -p,指定生成的java包名
- -wsdllocation,指定生成的java中wsdl的路径
- wsdl文件路径,通常会将wsdl保存为本地文件
注意的点
@WebServiceClient的类
生成后的文件,先找到一个注解有javax.xml.ws.WebServiceClient的类,这个类对应着wsdl文件中的service元素
<service name="service_name">
</service>
这个类通常指定了wsdl的位置及namespaceURI,
import javax.xml.ws.Service;
@WebServiceClient(name = "SomeService", targetNamespace = "http://some.domain", wsdlLocation = "http://domain.com/path/some.wsdl")
public class SomeService
extends Service
{
private final static URL PREFIX_WSDL_LOCATION;
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://domain.com/path/some.wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
PREFIX_WSDL_LOCATION= url;
}
}
@WebService的类
找到注解有 javax.jws.WebService的类,这个类对应着wsdl文件中的portType元素。
<portType name="SomePortType">
<operation name="operation_name">
<documentation>Service definition of function ns__operation_name</documentation>
<input message="输入参数"/>
<output message="输出参数"/>
</operation>
</portType>
这个类中通常会定义了很多方法,
@WebService(name = "SomePortType", targetNamespace = "http://some.domain")
@XmlSeeAlso({
com.package.ObjectFactory.class
})
public interface SomePortType {
@WebMethod(operationName = "someOperation")
@WebResult(name = "someResult", targetNamespace = "")
//省略
public String someOperation(
@WebParam(name = "输入参数1", targetNamespace = "")
String someInput,
@WebParam(name = "输入参数2", targetNamespace = "")
String someInput2);
ObjectFactory
还有一个ObjectFactory类,但
import javax.xml.bind.annotation.XmlRegistry;
@XmlRegistry
public class ObjectFactory {}
基本用法
注解有WebServiceClient的类 someService = new 注解有WebServiceClient的类;
final SomePortType somePortType = someService.getSome();
final String 输出参数 = somePortType.目标方法(输入参数)
好用的SOAP ui测试工具
我们先直观的感受下wsdl文件,wsdl文件用来描述一个webservice提供了哪些服务;比如天气webservice,http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
,浏览器中打开如下
最重要的是wsdl:service
节点,提供了4个端口,2个webservice、2个http的。
<wsdl:service name="WeatherWebService">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">.....</wsdl:documentation>
<wsdl:port name="WeatherWebServiceSoap" binding="tns:WeatherWebServiceSoap">
<soap:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceSoap12" binding="tns:WeatherWebServiceSoap12">
<soap12:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceHttpGet" binding="tns:WeatherWebServiceHttpGet">
<http:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceHttpPost" binding="tns:WeatherWebServiceHttpPost">
<http:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
</wsdl:service>
就像postman是http的ui客户端,SoapUI是web service的ui客户端,用来测试非常方便,注意下载开源版。
新建SOAP project,输入wsdl地址,http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
,点击能看到定义服务的URI和SOAP版本等信息,WeatherWebServiceSoap是SOAP 1.1版本,WeatherWebServiceSoap12是SOAP 1.2版本。
双击Request 1,点击绿色箭头就可以执行了,右侧是执行结果。
webservice仍然是使用的http来通信的,只是发送的内容遵循SOAP格式要求,这一点可通过http log查看。
http的请求体
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://WebXml.com.cn/">
<soapenv:Header/>
<soapenv:Body>
<web:getSupportCity>
<!--Optional:-->
<web:byProvinceName>?</web:byProvinceName>
</web:getSupportCity>
</soapenv:Body>
</soapenv:Envelope>
http响应体
<?xml version="1.0" encoding="utf-8"?>
<soap:envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:body>
<getsupportcityresponse
xmlns="http://WebXml.com.cn/">
<getsupportcityresult>
<string>........</string>
</getsupportcityresult>
</getsupportcityresponse>
</soap:body>
</soap:envelope>