webService初试
背景
最近工作上需要将一些业务数据推送到各个门户网站,而各个门户网站上接收数据的方式不一样,有webservice和http两种方式,初次使用webservice,记录一下踩得一些坑。
使用
工具
使用hutool中的SoapClient配合SoapUi工具进行使用。
使用
SoapUi工具解析WSDL地址,得到这个地址提供的方法,再进入相应的方法,得到请求这个方法的xml结构。
例子中: 这个
WSDL提供了四个调用方法,然后点击Request1弹出右边部分。右边部分为对这个方法发起请求的xml结构,这时只需要通过hutool工具类SoapClient创建一个一致的xml请求结构后发起请求即可。直接上代码
1
2
3
4
5
6
7
8
9public static void main(String[] args) {
SoapClient client = SoapClient.create("url")
.setCharset(Charset.forName("utf-8"))
.setMethod("调用的方法名", "命名空间")
.setParam("参数名称", "参数值");
// 打印请求数据
log.info("webService请求: \n{}", client.getMsgStr(false));
client.send();
}
以上就完成了
webService的调用,使用上还是比较简单,主要是第一次使用webService,到处磕磕碰碰。
1.SoapUI解析错误
部分门户使用SoapUI直接解析对应的http://xxx/xxx.asmx?wsdl地址,出现以下报错:
Error loading [http://htgs.ccgp.gov.cn/GS8/services/Gs8WebService?wsdl]: org.apache.xmlbeans.XmlException: org.apache.xmlbeans.XmlException: error: The element type "hr" must be terminated by the matching end-tag 。
解决方案为通过浏览器进入这个地址,将这个页面中的内容保存为xx.wsdl文件,使用SoapUI加载这个文件。
1. 使用postman调用
在通过代码进行webService请求之前,实际上应该通过SoapUI发起请求,看是否能调用成功。(请求方式为上图右部分的绿色按钮)。但是有一个接口,由于使用http://xx地址解析失败后采用xx.wsdl文件的方式解析,这个接口一直不能发起请求。
解决方案为使用postman发起请求。设置头信息中text/xml; charset=UTF-8,然后body请求体中的参数修改为raw后选择XML(text/xml)后就可以发起对webService服务的请求。
3.请求数据
假设发起请求要携带的参数值为:
1 | <body> |
那么实际上是需要将这个参数值填入到对应位置,实际发起的请求中是需要将<和>等字符进行编码化。<和>。
1 | <body> |
4.请求地址中?wsdl
对webService的请求地址中是否需要?wsdl,就目前而言部分接口是需要,部分接口是不需要。这就使得调用是不知道需不需要带上,遇到过一个问题是这个接口实际上是不需要携带,但我在请求时携带了,然后请求返回的内容是这个访问地址的内容,还一直以为是请求的参数或者是姿势不对,排查了好久才找到问题。
5.返回处理
最让我觉得难受的是webService请求之后处理,因为对接了好几个门户网站,每个门户都返回一种不同的结构。情况非常多:
异常情况:A门户的异常返回的是重定向页面的内容还包含了图片的base64串。B门户调用过于频繁也是返回一个重定向页面的内容。
正常情况:A门户是在一种xml结构中的里层嵌入一个json串。B门户是在xml中用![[DATA]]的方式嵌入一个xml结构数据。然而AB门户的外层xml结构都不一致。
综上基本上每个门户的请求参数和返回都需要进行定制化,无法抽象出来达到通用。