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
结构都不一致。
综上基本上每个门户的请求参数和返回都需要进行定制化,无法抽象出来达到通用。