记录一下使用Postman及现在主流的框架来请求Soap webservice。
1.Postman方式
访问地址:http://ip:port/xxx.wsdl
请求类型:POST
Headers: Content-Type:text/xml
Body:
将body设置为raw类型,只需要修改以下xxx部分
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xxx="http://tempuri.org/xxx.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header></soapenv:Header>
<soapenv:Body>
<xxx:login xmlns="http://www.w3.org/2001/XMLSchema">
<user>123456</user>
<passwd>111111</passwd>
</xxx:login>
</soapenv:Body>
</soapenv:Envelope>
好了,现在postman会给你返回结果的
2.Retrofit+OkHttp3方式
public interface InterfaceCollect {
@Headers({"Content-Type: text/xml;charset=UTF-8"})//请求的Action,类似于方法名
@POST("xxx.wsdl")
Observable<ResponseEnvelope> request(@Body RequestEnvelope requestEnvelope);
}
public class InterfaceService {
private Retrofit retrofit;
private InterfaceCollect interfaceCollect;
private static Strategy strategy = new AnnotationStrategy();
private static Serializer serializer = new Persister(strategy);
private InterfaceService() {
//手动创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(CMConfigs.DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.writeTimeout(CMConfigs.DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(CMConfigs.DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.retryOnConnectionFailure(true);
builder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.header("Content-Type", "text/xml;charset=UTF-8") // 对于SOAP 1.1, 如果是soap1.2 应是Content-Type: application/soap+xml; charset=utf-8
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.client(builder.build())
.addConverterFactory(SimpleXmlConverterFactory.create(serializer))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(BASE_URL)
.build();
interfaceCollect = retrofit.create(InterfaceCollect.class);
}
private static class SingletonHolder {
private static final InterfaceService INSTANCE = new InterfaceService();
}
//获取单例
public static InterfaceService getInstance() {
return SingletonHolder.INSTANCE;
}
private <T> Subscription toSubscribe(Observable<T> o, Subscriber<T> s) {
return o.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s);
}
public void request(Subscriber<ResponseEnvelope> subscriber, RequestEnvelope envelope) {
Observable observable = interfaceCollect.request(envelope);
toSubscribe(observable, subscriber);
}
}
@Root(name = "soapenv:Envelope")
@NamespaceList({
@Namespace(reference = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi"),
@Namespace(reference = "http://www.w3.org/2001/XMLSchema", prefix = "xsd"),
@Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soapenv"),
@Namespace(reference = "http://tempuri.org/xxx.xsd", prefix = "xxx")
})
public class RequestEnvelope {
@Element(name = "soapenv:Body", required = false)
public RequestBody body;
}
RequestEnvelope以及子节点RequestBody都是为了拼装body部分(按需拼接),这里需要在RequestEnvelope中定义好命名空间。
postman中的请求body实现如下:
RequestEnvelope requestEnvelop = new RequestEnvelope();
RequestBody requestBody = new RequestBody();
RequestLoginModel requestModel = new RequestLoginModel();
requestModel.user = user.getText().toString();
requestModel.passwd = passwd.getText().toString();
requestModel.attribute = "http://www.w3.org/2001/XMLSchema";
requestBody.login = requestModel;
requestEnvelop.body = requestBody;
InterfaceService.getInstance().request(new ApiSubscriber<ResponseEnvelope>() {
@Override
public void onNext(ResponseEnvelope responseEnvelope) {
}
}, requestEnvelop);
返回的ResponseEnvelope同RequestEnvelope类似,请自行实现。
Over