1.导入依赖库
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
api 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
final libRetrofit = "2.3.0"
//retrofit:[https://github.com/square/retrofit]
api "com.squareup.retrofit2:retrofit:$libRetrofit"
api "com.squareup.retrofit2:converter-gson:$libRetrofit"
api "com.squareup.retrofit2:converter-scalars:$libRetrofit"
api 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
//webservice使用到的库
api("com.squareup.retrofit2:converter-simplexml:$libRetrofit") {
exclude group:'xpp3',module:'xpp3'
exclude group:'stax',module:'stax-api'
exclude group:'stax',module:'stax'
}
final libOkhttp = "3.8.1"
//okhttp:[https://github.com/square/okhttp]
api "com.squareup.okhttp3:okhttp:$libOkhttp"
api "com.squareup.okhttp3:logging-interceptor:$libOkhttp"
final libRxJava = "2.1.1"
//rxJava:[https://github.com/ReactiveX/RxJava],rxAndroid:[https://github.com/ReactiveX/RxAndroid]
api "io.reactivex.rxjava2:rxandroid:$libRxJava"
api "io.reactivex.rxjava2:rxjava:$libRxJava"
}
2.网络请求类
public class Requester {
private static final int CONNECT_TIMEOUT = 30; //请求超时时间,单位:s
private static final int READ_TIMEOUT = 60; //读写超时时间,单位:s
private static OkHttpClient.Builder builder;
/**
* 初始化OkHttpClient.Builder()
*/
public static void initBuilder(Context context, String[] certificates, String[] hosts, boolean isDebug) {
builder = new OkHttpClient.Builder();
if (isDebug) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(loggingInterceptor);
}
//配置缓存选项
File cacheFile = new File(Utils.getContext().getCacheDir(), "responses");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);// 50 MiB
Interceptor cacheInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetworkUtils.isConnected(Utils.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (NetworkUtils.isConnected(Utils.getContext())) {
int maxAge = 0;
// 有网络时, 不缓存, 最大保存时长为0
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
} else {
// 无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
}
};
Interceptor retry = new Interceptor() {
public int maxRetry = 3;//最大重试次数
private int retryNum = 0;//假如设置为3次重试的话,则最大可能请求4次(默认1次+3次重试)
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
Log.v("======", "Retry num:" + retryNum);
while (!response.isSuccessful() && retryNum < maxRetry) {
retryNum++;
Log.v("======", "Retry num:" + retryNum);
response = chain.proceed(request);
}
return response;
}
};
//设置缓存
builder.addNetworkInterceptor(cacheInterceptor);
builder.addInterceptor(cacheInterceptor);
builder.addInterceptor(retry);
// SSLSocketFactory sslSocketFactory = HttpsFactroy.getSSLSocketFactory(context, certificates);
// if (sslSocketFactory != null) {
// builder.sslSocketFactory(sslSocketFactory);
//
// }
if (certificates != null && certificates.length > 0) {
//证书验证
try {
Log.v("======", "有加载证书");
TrustManager[] trustManagers = HttpsFactroy.getTrustManager(context, certificates);
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
} catch (Exception e) {
e.printStackTrace();
}
}
if (hosts != null && hosts.length > 0) {
Log.v("======", "有域名验证");
builder.hostnameVerifier(HttpsFactroy.getHostnameVerifier(hosts));
} else {
Log.v("======", "没有域名验证");
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
builder.cache(cache);
//设置文件下载监听
builder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse
.newBuilder()
.body(new FileResponseBody(originalResponse))
.build();
}
});
builder.interceptors().add(new Interceptor() {
@Override
public okhttp3.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);
}
});
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.v("===", message);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(loggingInterceptor);
//设置超时
builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
// builder.writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
}
private static Strategy strategy = new AnnotationStrategy();
private static Serializer serializer = new Persister(strategy);
/**
* 构造retrofit请求api
*
* @param host host地址
* @param service retrofit请求api
* @param <T> retrofit请求api
* @return retrofit请求api
*/
public static <T> T getRequestAPI(String host, Class<T> service) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(host)
.client(builder.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(SimpleXmlConverterFactory.create(serializer))
.addConverterFactory(GsonConverterFactory.create())//此converter放在最后,因为不确定返回的数据是否为json
.build();
return retrofit.create(service);
}
}
3.请求的报文示例
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pm="http://www.test.com/">
<soap:Body>
<pm:getCustomerInfo>
<arg0>ECDED40ED572C5169C08B12344B87C488E4CFCCACC3436C55DF9E30E870AA8BFAD824400B370B712291291562CF823BE</arg0>
</pm:getCustomerInfo>
</soap:Body>
</soap:Envelope>
请求的实体类
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
@Root(name = "soap:Envelope")
@NamespaceList({
@Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap")
})
public class RequestEnvelope {
@Element(name = "soap:Body")
private RequestWsdlBody body;
public RequestWsdlBody getBody() {
return body;
}
public void setBody(RequestWsdlBody body) {
this.body = body;
}
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
@NamespaceList({
@Namespace(reference = "http://www.test.com/", prefix = "pm")
})
public class RequestWsdlBody {
@Element(name = "pm:getCustomerInfoNew" )
private RequestUserMsg requestUserMsg;
public RequestUserMsg getRequestUserMsg() {
return requestUserMsg;
}
public void setRequestUserMsg(RequestUserMsg requestUserMsg) {
this.requestUserMsg = requestUserMsg;
}
}
import org.simpleframework.xml.Element;
public class RequestUserMsg {
@Element(name = "arg0")
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
4.返回的报文
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getCustomerInfoNewResponse xmlns:ns2="http://www.test.com/">
<return>A9AA3AB67F89D9740372ED4B55E31694C2DE7AA713370438474DFC31C34B2A9FA337AC74ED60B83DE55290AF35F87B5979DE2036799AC5FA95C86D0980836C92FBDA74D05B240B52C56307675D2309F5</return>
</ns2:getCustomerInfoNewResponse>
</soap:Body>
</soap:Envelope>
返回的实体类
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
@Root(name = "soap:Envelope")
@NamespaceList({
@Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap")
})
public class ResponseEnvelope {
@Element(name = "Body")
private ResponseWsdlBody body;
public ResponseWsdlBody getBody() {
return body;
}
public void setBody(ResponseWsdlBody body) {
this.body = body;
}
}
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
@NamespaceList({
@Namespace(reference = "http://www.test.com/", prefix = "pm")
})
public class ResponseWsdlBody {
@Element(name = "getCustomerInfoNewResponse")
private ResponseUserMsg responseUserMsg;
public ResponseUserMsg getResponseUserMsg() {
return responseUserMsg;
}
public void setResponseUserMsg(ResponseUserMsg responseUserMsg) {
this.responseUserMsg = responseUserMsg;
}
}
import org.simpleframework.xml.Element;
public class ResponseUserMsg {
@Element(name = "return")
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
5.请求接口
import com.cloud.spdb.shp_payment.ws.online.RequestEnvelope;
import com.cloud.spdb.shp_payment.ws.online.ResponseEnvelope;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public interface RequestApiService {
@POST("/getCustomerInfoNew?wsdl")
Observable<ResponseEnvelope> requestUserMsg(@Body RequestEnvelope request_envelope);
}
请求实现
public Observable<ResponseEnvelope> requestUserMsg(String data) {
RequestEnvelope requestEnvelope = new RequestEnvelope();
RequestUserMsg requestUserMsg = new RequestUserMsg();
requestUserMsg.setData(data);
RequestWsdlBody requestBody = new RequestWsdlBody();
requestBody.setRequestUserMsg(requestUserMsg);
requestEnvelope.setBody(requestBody);
return requestAPI.requestUserMsg(requestEnvelope).map(new Function<ResponseEnvelope, ResponseEnvelope>() {
@Override
public ResponseEnvelope apply(@NonNull ResponseEnvelope responseEnvelope) throws Exception {
return responseEnvelope;
}
});
}