irpas技术客

「Android」孙正义|窥探OKHttp+Gson_FranzLiszt1847_android okhttp3封装

irpas 3267

窥探OKHttp+Gson Json 介绍创建对应格式化实体类安装插件GsonFormatPlus创建实体类踩坑笔记 Json数据解析引入依赖OkHttp封装JsonObject解析JsonArray解析回调完整封装 Json解析

Json 介绍 JsonObject 对应Json字符串中用{}包裹的数据,相当于一个实体类 JsonArray对应Json字符串中用[]包裹的数据,相当于一个数组

下面为从某个服务器中拉去的数据,其中data为数据核心部分,minfo为一个数组,其中包含所需要渲染的数据,filter为一个数据实体,包含筛选条件信息。

{ "status":"200", "msg ":"success", "source":"156", "data":{ "data_type":"2", "minfo":Array[30], "filter":{ "orderby":[ { "title":"Popular", "id":"1" }, Object{...}, Object{...} ], "genre":Array[27], "pub":Array[12], "type":Array[3], "country":Array[49] } } } 创建对应格式化实体类

从服务器端拉去的Json字符串,需要创建对应的实体类进行接收,本文介绍一种插件,用于Android端格式化建立实体类

安装插件GsonFormatPlus

点击设置->plugins->搜索并安装插件GsonFormatPlus插件

创建实体类

第一步,在需要创建实体类的地方右击空白处,在弹出的显示框中选择Generate

第二步,然后在选择刚才安装的插件GsonFormatPlus 第三步,最后将Json字符串复制上去,点击OK即可自动创建

踩坑笔记

如果你不想一次性创建所有的Json数据对于的实体类,也就是说,你所请求的Json字符串你不想创建在一个实体类中,比如下面Json字符串为例,下面的minfo是一个数组,如果你想把这个数组内的数据单独建立一个实体类,你需要把这个字段定义为JsonArray类型,注意不是全大写,全大写是另外一个类,会出错,JsonObject同理。这样可以让数据更加层次分明,在不同的地方引用时,较为方便。

private JsonArray orderby; { "status":"200", "msg ":"success", "source":"156", "data":{ "data_type":"2", "minfo":Array[30], "filter":{ "orderby":[ { "title":"Popular", "id":"1" }, Object{...}, Object{...} ], "genre":Array[27], "pub":Array[12], "type":Array[3], "country":Array[49] } } } Json数据解析 引入依赖 implementation 'com.squareup.okhttp3:okhttp:3.1.0' implementation 'com.squareup.okio:okio:1.5.0' implementation 'com.google.code.gson:gson:2.8.0' OkHttp封装

将请求体用map进行键值对进行添加,然后使用表单进行提交。在建立Request对象将请求体进行上传,然后在newCall中接受服务器回调,此类是一个封装类,只取出第一层数据体,因为不同的接口所返回的数据内容不一样,Json体也不一样,所有此处只对第一层进行解析,然后在不同的地方调用时,在进行具体解析。

/** * @param url connect server address * @param map request param * @param callback bind success or fail callback*/ public void Post(String url,Map<String,Object> map,HttpCallback callback) { OkHttpClient client = new OkHttpClient(); FormBody.Builder requestBuild = new FormBody.Builder(); for (Map.Entry<String,Object> mEntry : map.entrySet()) { requestBuild.add(mEntry.getKey(),mEntry.getValue()+""); } RequestBody requestBody = requestBuild.build(); Request request = new Request.Builder() .url(url) .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("getInternetData","error message = "+e.getMessage()); callback.onFailure(ErrorParam.POSTINGERROR); } @Override public void onResponse(Call call, Response response) throws IOException { String body = response.body().string(); int code = response.code(); if (code == 200){ try { JSONObject jsonObject = new JSONObject(body); int status_code = jsonObject.getInt("status"); if (status_code == 200){ String data = jsonObject.getString("data"); callback.onResponse(data); }else { callback.onFailure(ErrorParam.NETWORKERROR);//net error } } catch (JSONException e) { Log.e("getBannerData","error"); callback.onFailure(ErrorParam.RESOLVINGERROR);//resolve error e.printStackTrace(); } }else { callback.onFailure(ErrorParam.SERVERERROR);//service error } } }); } JsonObject解析 * resolve jsonboject*/ public static <T> T fromJson(String josn,Class<T> c){ Gson gson = new Gson(); T t = null; return t = gson.fromJson(josn,c); } JsonArray解析 public static <T> List<T> fromListJson(String json,Class<T> c){ List<T> list = new ArrayList<>(); Gson gson = new Gson(); JsonArray array = new JsonParser().parse(json).getAsJsonArray(); for (final JsonElement element: array) { list.add(gson.fromJson(element,c)); } return list; } 回调

建立一个回调接口,将解析结果暴露给外部

public interface HttpCallback<T> { void onFailure(int error); void onResponse(T data) throws JSONException; } 完整封装

因为隐私,服务器接口和请求体暂不外露,其余内容如下所示

public class OKHttpUtils { private static Map<String,Object> map = new HashMap<>(); private static OKHttpUtils singleton; private OKHttpUtils(){ } public static OKHttpUtils getInstance(){ if (singleton == null){ Sync(); } return singleton; } private static synchronized void Sync(){ if (singleton == null){ singleton = new OKHttpUtils(); InitMap(); } } /** * @param url connect server address * @param map request param * @param callback bind success or fail callback*/ public void Post(String url,Map<String,Object> map,HttpCallback callback) { OkHttpClient client = new OkHttpClient(); FormBody.Builder requestBuild = new FormBody.Builder(); for (Map.Entry<String,Object> mEntry : map.entrySet()) { requestBuild.add(mEntry.getKey(),mEntry.getValue()+""); } RequestBody requestBody = requestBuild.build(); Request request = new Request.Builder() .url(url) .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("getInternetData","error message = "+e.getMessage()); callback.onFailure(ErrorParam.POSTINGERROR); } @Override public void onResponse(Call call, Response response) throws IOException { String body = response.body().string(); Log.d("sss",body.toString()); int code = response.code(); if (code == 200){ try { JSONObject jsonObject = new JSONObject(body); int status_code = jsonObject.getInt("status"); if (status_code == 200){ String data = jsonObject.getString("data"); callback.onResponse(data); }else { callback.onFailure(ErrorParam.NETWORKERROR);//net error } } catch (JSONException e) { Log.e("getBannerData","error"); callback.onFailure(ErrorParam.RESOLVINGERROR);//resolve error e.printStackTrace(); } }else { callback.onFailure(ErrorParam.SERVERERROR);//service error } } }); } /** * public request param*/ private static void InitMap(){ //因为隐私,请求体省略 } public Map<String,Object> getMap(){ return map; } public String setUrl(String port){ return PortParam.BaseUrl+port; } /** * resolve jsonboject*/ public static <T> T fromJson(String josn,Class<T> c){ Gson gson = new Gson(); T t = null; return t = gson.fromJson(josn,c); } /** * resolve jsonarray*/ public static <T> List<T> fromListJson(String json,Class<T> c){ List<T> list = new ArrayList<>(); Gson gson = new Gson(); JsonArray array = new JsonParser().parse(json).getAsJsonArray(); for (final JsonElement element: array) { list.add(gson.fromJson(element,c)); } return list; } } Json解析

然后在外部进行服务器地址、请求体上传,在进行进一步解析,在下面通过刚刚建立的回调接口,在OnFailure()中进行错误解析回调,并处理;在OnResponse()中进行json字符串获取,此字符串已经被解析了一层,在根据不同的接口回调,做出不同响应即可,此处将获取的json字符串转为数组形式。

private void Post(){ OKHttpUtils utils = OKHttpUtils.getInstance(); Map<String,Object> map = utils.getMap(); //内容省略...map.put("",""); utils.Post(utils.setUrl(PortParam.TvShowsPort), map, new HttpCallback() { @Override public void onFailure(int error) { switch (error){ case ErrorParam.NETWORKERROR: break; case ErrorParam.SERVERERROR: break; case ErrorParam.RESOLVINGERROR: break; case ErrorParam.POSTINGERROR: handler.sendEmptyMessage(4); break; } } @Override public void onResponse(Object data) throws JSONException { array = new JSONArray(data.toString()); handler.sendEmptyMessage(0); } }); }

然后使用rxjava进行监听,此框架一目了然,subscribe()建立被观察者,subscribe()建立观察者,然后onNext()、onComplete(),此处回调的数据较多,又分为不同的场景,头部有一个轮播图baner数据,下面有一个RecyclerView嵌套RecyclerView,需要根据判断解析的Display_type判断其显示方式,从而决定RecyclerView是横向显示还是竖向显示。最后通过handler异步渲染UI。

private void UpdateUI(){ Observable.create(new ObservableOnSubscribe<FeaturedData>() { @Override public void subscribe(@NotNull ObservableEmitter<FeaturedData> observableEmitter) throws Exception { if (featuredDataList != null){ for (int i = 0; i < featuredDataList.size(); i++) { if (featuredDataList.get(i).getData_type().equals("1")){ observableEmitter.onNext(featuredDataList.get(i)); } } observableEmitter.onComplete(); } } }).subscribe(new Observer<FeaturedData>() { @Override public void onSubscribe(@NotNull Disposable disposable) { } @Override public void onNext(@NotNull FeaturedData featuredData) { if (featuredData.getName().equals("Banner")){ try { JSONArray array = new JSONArray(featuredData.getData().toString()); featureBannerDataList = OKHttpUtils.fromListJson(array.toString(),FeatureBannerData.class); //update banner handler.sendEmptyMessage(2); } catch (JSONException e) { e.printStackTrace(); } }else if (featuredData.getDisplay_type().equals("1")){ //v JSONArray jsonArray = null; JSONObject object = null; try { jsonArray = new JSONArray(featuredData.getData().toString()); object = jsonArray.getJSONObject(0); } catch (JSONException e) { e.printStackTrace(); } FeatureInnerData data = OKHttpUtils.fromJson(object.toString(),FeatureInnerData.class); data.setSlide_way(1); featureInnerDataList.add(data); }else { //H JSONArray jsonArray = null; JSONObject object = null; try { jsonArray = new JSONArray(featuredData.getData().toString()); object = jsonArray.getJSONObject(0); } catch (JSONException e) { e.printStackTrace(); } FeatureInnerData data = OKHttpUtils.fromJson(object.toString(),FeatureInnerData.class); data.setSlide_way(2); featureInnerDataList.add(data); } } @Override public void onError(@NotNull Throwable throwable) { } @Override public void onComplete() { handler.sendEmptyMessage(3); } }); }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Android #okhttp3封装