ObservableRequests.java 14 KB

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