ObservableRequests.java 14 KB

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