1.導(dǎo)入依賴庫(kù)
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使用到的庫(kù)
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.網(wǎng)絡(luò)請(qǐng)求類(lèi)
public class Requester {
private static final int CONNECT_TIMEOUT = 30; //請(qǐng)求超時(shí)時(shí)間,單位:s
private static final int READ_TIMEOUT = 60; //讀寫(xiě)超時(shí)時(shí)間,單位: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);
}
//配置緩存選項(xiàng)
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;
// 有網(wǎng)絡(luò)時(shí), 不緩存, 最大保存時(shí)長(zhǎng)為0
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
} else {
// 無(wú)網(wǎng)絡(luò)時(shí),設(shè)置超時(shí)為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;//最大重試次數(shù)
private int retryNum = 0;//假如設(shè)置為3次重試的話,則最大可能請(qǐng)求4次(默認(rèn)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;
}
};
//設(shè)置緩存
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) {
//證書(shū)驗(yàn)證
try {
Log.v("======", "有加載證書(shū)");
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("======", "有域名驗(yàn)證");
builder.hostnameVerifier(HttpsFactroy.getHostnameVerifier(hosts));
} else {
Log.v("======", "沒(méi)有域名驗(yàn)證");
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
builder.cache(cache);
//設(shè)置文件下載監(jiān)聽(tīng)
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") // 對(duì)于SOAP 1.1, 如果是soap1.2 應(yīng)是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);
//設(shè)置超時(shí)
builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
// builder.writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
//錯(cuò)誤重連
builder.retryOnConnectionFailure(true);
}
private static Strategy strategy = new AnnotationStrategy();
private static Serializer serializer = new Persister(strategy);
/**
* 構(gòu)造retrofit請(qǐng)求api
*
* @param host host地址
* @param service retrofit請(qǐng)求api
* @param <T> retrofit請(qǐng)求api
* @return retrofit請(qǐng)求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放在最后,因?yàn)椴淮_定返回的數(shù)據(jù)是否為json
.build();
return retrofit.create(service);
}
}
3.請(qǐng)求的報(bào)文示例
<?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>
請(qǐng)求的實(shí)體類(lèi)
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.返回的報(bào)文
<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>
返回的實(shí)體類(lèi)
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.請(qǐng)求接口
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);
}
請(qǐng)求實(shí)現(xiàn)
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;
}
});
}