ObservableRequests.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. package com.mylove.okhttp;
  2. import android.annotation.SuppressLint;
  3. import android.content.Context;
  4. import android.support.annotation.NonNull;
  5. import android.util.Log;
  6. import com.google.gson.Gson;
  7. import org.json.XML;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.Map;
  11. import java.util.concurrent.TimeUnit;
  12. import io.reactivex.Observable;
  13. import io.reactivex.ObservableEmitter;
  14. import io.reactivex.ObservableOnSubscribe;
  15. import io.reactivex.Observer;
  16. import io.reactivex.android.schedulers.AndroidSchedulers;
  17. import io.reactivex.disposables.Disposable;
  18. import io.reactivex.schedulers.Schedulers;
  19. import okhttp3.Call;
  20. import okhttp3.Callback;
  21. import okhttp3.FormBody;
  22. import okhttp3.MediaType;
  23. import okhttp3.MultipartBody;
  24. import okhttp3.OkHttpClient;
  25. import okhttp3.Request;
  26. import okhttp3.RequestBody;
  27. import okhttp3.Response;
  28. /**
  29. * @author myLove
  30. */
  31. class ObservableRequests<T> {
  32. @SuppressLint("StaticFieldLeak")
  33. private static ObservableRequests instance;
  34. @SuppressLint("StaticFieldLeak")
  35. private static Context mContext;
  36. private static RequestType requestType;
  37. private static CallType callType;
  38. private static OkHttpClient okHttpClient;
  39. private String mCacheUrl = "";
  40. public Class<T> tClass;
  41. static ObservableRequests getInstance(Context context, RequestType type1, CallType type2) {
  42. if (instance == null) {
  43. synchronized (ObservableRequests.class) {
  44. if (instance == null) {
  45. instance = new ObservableRequests();
  46. OkHttpClient httpClient = new OkHttpClient();
  47. okHttpClient = httpClient.newBuilder()
  48. .addNetworkInterceptor(new CacheInterceptor())
  49. .addInterceptor(Cache.HTTP_LOGGING_INTERCEPTOR)
  50. .cache(Cache.privateCache(context))
  51. .connectTimeout(30, TimeUnit.SECONDS)
  52. .readTimeout(30, TimeUnit.SECONDS)
  53. .build();
  54. }
  55. }
  56. }
  57. mContext = context;
  58. requestType = type1;
  59. callType = type2;
  60. return instance;
  61. }
  62. void request(String url, Map<Object, Object> oMap, final onOkHttpListener onOkHttpListener) {
  63. getObservable(url, oMap).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
  64. .serialize().subscribe(new Observer<T>() {
  65. @Override
  66. public void onSubscribe(Disposable d) {
  67. }
  68. @Override
  69. public void onNext(T t) {
  70. onOkHttpListener.onSuccess(t);
  71. }
  72. @Override
  73. public void onError(Throwable e) {
  74. onOkHttpListener.onFailure(e);
  75. }
  76. @Override
  77. public void onComplete() {
  78. onOkHttpListener.onCompleted();
  79. }
  80. });
  81. }
  82. private Observable<T> getObservable(final String url, final Map<Object, Object> oMap) {
  83. return Observable.create(new ObservableOnSubscribe<T>() {
  84. @Override
  85. public void subscribe(ObservableEmitter<T> e) {
  86. send(url, oMap, e);
  87. }
  88. });
  89. }
  90. private void send(String url, Map<Object, Object> map, ObservableEmitter<T> subscriber) {
  91. if (FormatUtil.isMapNotEmpty(map)) {
  92. mCacheUrl = url + map.toString();
  93. } else {
  94. mCacheUrl = url;
  95. }
  96. InternetBean bean = Internet.ifInternet(mContext);
  97. if (bean.getStatus()) {
  98. Call call = okHttpClient.newCall(getRequest(url, map));
  99. sendCall(call, subscriber);
  100. } else {
  101. String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
  102. if (FormatUtil.isNotEmpty(json)) {
  103. T t = new Gson().fromJson(json, tClass);
  104. subscriber.onNext(t);
  105. } else {
  106. subscriber.onError(new Error(bean.getMsg()));
  107. }
  108. subscriber.onComplete();
  109. }
  110. }
  111. /**
  112. * 请求
  113. */
  114. private void sendCall(Call call, ObservableEmitter<T> subscriber) {
  115. if (callType == CallType.SYNC) {
  116. sync(call, subscriber);
  117. } else if (callType == CallType.ASYNC) {
  118. async(call, subscriber);
  119. }
  120. }
  121. /**
  122. * 同步请求
  123. */
  124. private void sync(Call call, ObservableEmitter<T> subscriber) {
  125. try {
  126. Response execute = call.execute();
  127. if (execute.isSuccessful()) {
  128. String str = execute.body().string();
  129. if (OkHttpInfo.isLOG) {
  130. Log.v(OkHttpInfo.TAG, str);
  131. }
  132. if ((str.substring(0, 1).equals("<") || str.substring(0, 1).equals("["))
  133. && (str.substring(1, 2).equals("\"") || str.substring(1, 2).equals("["))) {
  134. try {
  135. str = XML.toJSONObject(str).toString();
  136. } catch (Exception e) {
  137. e.printStackTrace();
  138. }
  139. if (!str.toUpperCase().contains("<!DOCTYPE HTML>")) {
  140. if (FormatUtil.isNotEmpty(mCacheUrl)) {
  141. CacheUtils.getInstance(mContext).setCacheToLocalJson(mCacheUrl, str);
  142. }
  143. }
  144. }
  145. T t = new Gson().fromJson(str, tClass);
  146. subscriber.onNext(t);
  147. subscriber.onComplete();
  148. } else {
  149. String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
  150. if (FormatUtil.isNotEmpty(json)) {
  151. T t = new Gson().fromJson(json, tClass);
  152. subscriber.onNext(t);
  153. } else {
  154. subscriber.onError(new Exception("请求失败"));
  155. }
  156. subscriber.onComplete();
  157. }
  158. } catch (IOException e) {
  159. String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
  160. if (FormatUtil.isNotEmpty(json)) {
  161. T t = new Gson().fromJson(json, tClass);
  162. subscriber.onNext(t);
  163. } else {
  164. subscriber.onError(e);
  165. }
  166. e.printStackTrace();
  167. subscriber.onComplete();
  168. }
  169. }
  170. /**
  171. * 异步请求
  172. */
  173. private void async(Call call, final ObservableEmitter<T> subscriber) {
  174. call.enqueue(new Callback() {
  175. @Override
  176. public void onFailure(@NonNull Call call, @NonNull IOException e) {
  177. String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
  178. if (FormatUtil.isNotEmpty(json)) {
  179. T t = new Gson().fromJson(json, tClass);
  180. subscriber.onNext(t);
  181. } else {
  182. subscriber.onError(e);
  183. }
  184. e.printStackTrace();
  185. subscriber.onComplete();
  186. }
  187. @Override
  188. public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
  189. String str = response.body().string();
  190. if (OkHttpInfo.isLOG) {
  191. Log.v(OkHttpInfo.TAG, str);
  192. }
  193. if ((str.substring(0, 1).equals("<") || str.substring(0, 1).equals("["))
  194. && (str.substring(1, 2).equals("\"") || str.substring(1, 2).equals("["))) {
  195. try {
  196. str = XML.toJSONObject(str).toString();
  197. } catch (Exception e) {
  198. e.printStackTrace();
  199. }
  200. if (!str.toUpperCase().contains("<!DOCTYPE HTML>")) {
  201. if (FormatUtil.isNotEmpty(mCacheUrl)) {
  202. CacheUtils.getInstance(mContext).setCacheToLocalJson(mCacheUrl, str);
  203. }
  204. }
  205. }
  206. T t = new Gson().fromJson(str, tClass);
  207. subscriber.onNext(t);
  208. subscriber.onComplete();
  209. }
  210. });
  211. }
  212. /**
  213. * 判断请求方式
  214. *
  215. * @param url 地址
  216. * @param oMap 键值
  217. * @return request
  218. */
  219. private Request getRequest(String url, Map<Object, Object> oMap) {
  220. if (requestType == null) {
  221. requestType = RequestType.POST;
  222. }
  223. switch (requestType) {
  224. case GET:
  225. return get(url, oMap);
  226. case POST_XML_SOAP:
  227. return postXMLToSoap(url, oMap);
  228. case UP_FILE:
  229. return upFile(url, oMap);
  230. case ALL:
  231. return upAll(url, oMap);
  232. case POST:
  233. default:
  234. return post(url, oMap);
  235. }
  236. }
  237. private Request postXMLToSoap(String url, Map<Object, Object> oMap) {
  238. if (FormatUtil.isEmpty(OkHttpInfo.soapDataTopString)) {
  239. throw new NullPointerException("OkHttpInfo.soapDataTopString不能为空");
  240. }
  241. if (FormatUtil.isEmpty(OkHttpInfo.soapDataBottomString)) {
  242. throw new NullPointerException("OkHttpInfo.soapDataBottomString不能为空");
  243. }
  244. StringBuilder sb = new StringBuilder();
  245. if (FormatUtil.isMapNotEmpty(oMap)) {
  246. for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
  247. String key = entry.getKey().toString();
  248. String value = entry.getValue().toString();
  249. sb.append("<").append(key).append(">").append(value).append("</").append(key).append(">");
  250. }
  251. }
  252. MediaType mediaType = MediaType.parse(OkHttpInfo.soapMediaType);
  253. String str = OkHttpInfo.soapDataTopString + sb + OkHttpInfo.soapDataBottomString;
  254. if (OkHttpInfo.isLOG) {
  255. Log.v(OkHttpInfo.TAG, str);
  256. }
  257. return new Request.Builder()
  258. .url(url)
  259. .post(RequestBody.create(mediaType, str))
  260. .build();
  261. }
  262. /**
  263. * 上传文件
  264. *
  265. * @param url 地址
  266. * @param oMap 键值
  267. * @return request
  268. */
  269. private Request upFile(String url, Map<Object, Object> oMap) {
  270. MultipartBody.Builder builder = new MultipartBody.Builder()
  271. .setType(MultipartBody.FORM);
  272. if (FormatUtil.isMapNotEmpty(oMap)) {
  273. for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
  274. File file = new File(entry.getValue().toString());
  275. int indexOf = entry.getValue().toString().indexOf("/");
  276. RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
  277. String fileName = entry.getKey().toString().substring(indexOf + 1, entry.getKey().toString().length());
  278. builder.addFormDataPart(entry.getKey().toString(), fileName, requestBody);
  279. }
  280. }
  281. MultipartBody multipartBody = builder.build();
  282. return new Request.Builder()
  283. .url(url)
  284. .post(multipartBody)
  285. .build();
  286. }
  287. /**
  288. * 参数和文件一起上传
  289. *
  290. * @param url 地址
  291. * @param oMap 键值
  292. * @return request
  293. */
  294. private Request upAll(String url, Map<Object, Object> oMap) {
  295. MultipartBody.Builder builder = new MultipartBody.Builder()
  296. .setType(MultipartBody.ALTERNATIVE);
  297. if (FormatUtil.isMapNotEmpty(oMap)) {
  298. for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
  299. int indexOf = entry.getValue().toString().lastIndexOf("/");
  300. int indexOf1 = entry.getValue().toString().lastIndexOf(".");
  301. if (indexOf > 0 && indexOf1 > 0) {
  302. File file = new File(entry.getValue().toString());
  303. RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
  304. String fileName = entry.getKey().toString().substring(indexOf + 1, entry.getKey().toString().length());
  305. builder.addFormDataPart(entry.getKey().toString(), fileName, requestBody);
  306. } else {
  307. builder.addFormDataPart(entry.getKey().toString(), entry.getValue().toString());
  308. }
  309. }
  310. }
  311. MultipartBody multipartBody = builder.build();
  312. return new Request.Builder()
  313. .url(url)
  314. .post(multipartBody)
  315. .build();
  316. }
  317. /**
  318. * get上传参数
  319. *
  320. * @param url 地址
  321. * @param oMap 键值
  322. * @return request
  323. */
  324. private Request get(String url, Map<Object, Object> oMap) {
  325. StringBuilder str = new StringBuilder(url);
  326. if (FormatUtil.isMapNotEmpty(oMap)) {
  327. str.append("?");
  328. for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
  329. str.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
  330. }
  331. str = new StringBuilder(str.substring(0, str.length() - 1));
  332. }
  333. if (OkHttpInfo.isLOG) {
  334. Log.v(OkHttpInfo.TAG, str.toString());
  335. }
  336. return new Request.Builder()
  337. .url(str.toString())
  338. .get()
  339. .build();
  340. }
  341. /**
  342. * post上传参数
  343. *
  344. * @param url 地址
  345. * @param oMap 键值
  346. * @return request
  347. */
  348. private Request post(String url, Map<Object, Object> oMap) {
  349. FormBody.Builder builder = new FormBody.Builder();
  350. if (FormatUtil.isMapNotEmpty(oMap)) {
  351. for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
  352. builder.add(entry.getKey().toString(), entry.getValue().toString());
  353. }
  354. }
  355. FormBody build = builder.build();
  356. return new Request.Builder()
  357. .url(url)
  358. .post(build)
  359. .build();
  360. }
  361. }