在retrofit访问网络返回json数据添加解析器
2017-06-10 18:05
381 查看
1、
在上个头条新闻的项目中我解析的数据是聚合数据返回的
如果你不加解析器
那么retrofit 返回的数据是默认的格式
在默认情况下Retrofit只支持将HTTP的响应体转换换为ResponseBody
2、源码可以看到call方法返回类型是
支持泛型。
在默认情况下Retrofit只支持将HTTP的响应体转换换为ResponseBody, 这也是什么我在前面的例子接口的返回值都是 Call, 但如果响应体只是支持转换为ResponseBody的话何必要引用泛型呢, 返回值直接用一个Call就行了嘛,既然支持泛型,那说明泛型参数可以是其它类型的, 而Converter就是Retrofit为我们提供用于将ResponseBody转换为我们想要的类型
参考:
http://www.cnblogs.com/xl-phoenix/p/6854841.html
装换器就是把服务器返回的json格式数据,多做了一步处理,装换成你希望的类型,比如:
这里我重点讲使用
1、通用的返回类型
如果你返回的数据最外层是
jsonobject不能转jsonarray,否则出错
Exception in thread “main” com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2
2、如果我要直接将返回数据装换成student
1)方法1是自定义装换器,我上篇博客有写。
http://blog.csdn.net/vae260772/article/details/72933978
2)如果我要用
实现要怎么做???
答案是可以的。GSON很强大的,会自动识别json数据,我们要写一个和json数据格式对应pojo类(就是model,比如student)
参考:http://www.cnblogs.com/jianyungsun/p/6647203.html
HttpResult.java
这里面hello123error_code 是我故意写错的,应该是error_code,和json原始数据一模一样,才能对应。
Result .java类
[{},{},…,{}] 这个是一个json数组,转换成类 就是一个List,怎么转换的,这个是gson包里面写的,感兴趣可以研究吧。
写Data.java
好了,这样子之后就可以
使用GSON
将原始 服务器的json数据—>HttpResult对象
如果你使用retrofit+rxjava
添加addCallAdapterFactory
需要修改借口返回的类型,对应泛型修改HttpResult
访问的数据类型 对应 HttpResult:
好了,就是这样子。注意json格式
原始2个:
[ ….] json数组
{… } json对象
对应json返回写
封装类,有 对象、list等。注意名称和json一致。
大致如此。。。
在上个头条新闻的项目中我解析的数据是聚合数据返回的
{ "reason":"成功的返回", "result":{ "stat":"1", "data":[ { "uniquekey":"696313d4f1363ee18e3f7f72f3cd4ed0", "title":"南方多地现暴雨:南京发布今年首个红色预警", "date":"2017-06-10 15:30", "category":"社会", "author_name":"封面新闻", "url":"http:\/\/mini.eastday.com\/mobile\/170610153027054.html", "thumbnail_pic_s":"http:\/\/03.imgmini.eastday.com\/mobile\/20170610\/20170610153027_f6fc3dc1ef75faf01525fe62f47d6901_4_mwpm_03200403.jpeg", "thumbnail_pic_s02":"http:\/\/03.imgmini.eastday.com\/mobile\/20170610\/20170610153027_f6fc3dc1ef75faf01525fe62f47d6901_3_mwpm_03200403.jpeg", "thumbnail_pic_s03":"http:\/\/03.imgmini.eastday.com\/mobile\/20170610\/20170610153027_f6fc3dc1ef75faf01525fe62f47d6901_2_mwpm_03200403.jpeg" }, { "uniquekey":"b249f8a0fc67671a2bb505c24e0e5ce2", "title":"邵阳一患有精神疾病女子失踪 家人苦苦寻找14年", "date":"2017-06-10 15:33", "category":"社会", "author_name":"中国失踪人口档案库", "url":"http:\/\/mini.eastday.com\/mobile\/170610153321293.html", "thumbnail_pic_s":"http:\/\/06.imgmini.eastday.com\/mobile\/20170610\/20170610153321_9809a52d7ed284ce29cbf1987d879b8d_1_mwpm_03200403.jpeg" }, ...类似上面 ,{ "uniquekey":"b563abac04025cda01c9099a84d2c4f7", "title":"农村一捞一大把没人要,城里人却为它疯狂,尤其在夜市最受欢迎", "date":"2017-06-10 14:42", "category":"社会", "author_name":"鹦鹉爱情鸟", "url":"http:\/\/mini.eastday.com\/mobile\/170610144206081.html", "thumbnail_pic_s":"http:\/\/00.imgmini.eastday.com\/mobile\/20170610\/20170610_f4c6ccab71aa195ff6c40ab1bf174e34_cover_mwpm_03200403.jpeg", "thumbnail_pic_s02":"http:\/\/00.imgmini.eastday.com\/mobile\/20170610\/20170610_155b79f8b471caabf08716666cf85f2c_cover_mwpm_03200403.jpeg", "thumbnail_pic_s03":"http:\/\/00.imgmini.eastday.com\/mobile\/20170610\/20170610_8aee78d02533f3fcfc3faeca59acb9d8_cover_mwpm_03200403.jpeg" } ] }, "error_code":0 }
如果你不加解析器
Retrofit retrofit = new Retrofit.Builder(). baseUrl("http://v.juhe.cn/") //.addConverterFactory(CustomConverterFactory.create()) //.addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
那么retrofit 返回的数据是默认的格式
在默认情况下Retrofit只支持将HTTP的响应体转换换为ResponseBody
call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Response<ResponseBody> response, Retrofit retrofit) { try { System.out.println(response.body().string()); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Throwable t) { t.printStackTrace(); } });
2、源码可以看到call方法返回类型是
<T>
支持泛型。
在默认情况下Retrofit只支持将HTTP的响应体转换换为ResponseBody, 这也是什么我在前面的例子接口的返回值都是 Call, 但如果响应体只是支持转换为ResponseBody的话何必要引用泛型呢, 返回值直接用一个Call就行了嘛,既然支持泛型,那说明泛型参数可以是其它类型的, 而Converter就是Retrofit为我们提供用于将ResponseBody转换为我们想要的类型
转换器可以被添加到支持其他类型。提供了方便适应流行的串行化库, Retrofit 提供了六兄弟模块如下: Gson: com.squareup.retrofit:converter-gson Jackson: com.squareup.retrofit:converter-jackson Moshi: com.squareup.retrofit:converter-moshi Protobuf: com.squareup.retrofit:converter-protobuf Wire: com.squareup.retrofit:converter-wire Simple XML: com.squareup.retrofit:converter-simplexml
参考:
http://www.cnblogs.com/xl-phoenix/p/6854841.html
装换器就是把服务器返回的json格式数据,多做了一步处理,装换成你希望的类型,比如:
student teacher List<student> string
这里我重点讲使用
Gson: com.squareup.retrofit:converter-gson
1、通用的返回类型
如果你返回的数据最外层是
{....}格式: 最外层是一个对象,那么你可以返回 JsonObject,然后再转换成 student对象 [...] 格式: 最外层是一个数组, 那么你可以返回 JsonArray ,然后再转换成 list<student> 对象
jsonobject不能转jsonarray,否则出错
Exception in thread “main” com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2
2、如果我要直接将返回数据装换成student
1)方法1是自定义装换器,我上篇博客有写。
http://blog.csdn.net/vae260772/article/details/72933978
2)如果我要用
Gson: com.squareup.retrofit:converter-gson
实现要怎么做???
答案是可以的。GSON很强大的,会自动识别json数据,我们要写一个和json数据格式对应pojo类(就是model,比如student)
参考:http://www.cnblogs.com/jianyungsun/p/6647203.html
HttpResult.java
package com.example.lihui20.testhttp.model; /** * Created by lihui on 2017/6/10. */ public class HttpResult { String reason; Result result; String hello123error_code; public String getReason() { return reason; } public String getError_code() { return hello123error_code; } public void setError_code(String error_code) { this.hello123error_code = error_code; } public void setReason(String reason) { this.reason = reason; } public Result getResult() { return result; } public void setResult(Result result) { this.result = result; } @Override public String toString() { return "HttpResult{" + "reason='" + reason + '\'' + ", result=" + result + ", error_code='" + hello123error_code + '\'' + '}'; } }
这里面hello123error_code 是我故意写错的,应该是error_code,和json原始数据一模一样,才能对应。
Result .java类
package com.example.lihui20.testhttp.model; import java.util.List; /** * Created by lihui on 2017/6/10. */ public class Result { String stat; List<Data> data; public String getStat() { return stat; } public void setStat(String stat) { this.stat = stat; } public List<Data> getList() { return data; } public void setList(List<Data> data) { this.data = data; } @Override public String toString() { return "Result{" + "stat='" + stat + '\'' + ", data=" + data + '}'; } }
[{},{},…,{}] 这个是一个json数组,转换成类 就是一个List,怎么转换的,这个是gson包里面写的,感兴趣可以研究吧。
写Data.java
package com.example.lihui20.testhttp.model; import org.json.JSONObject; /** * Created by lihui20 on 2016/12/6. */ public class Data { String title; String date; String author_name; String thumbnail_pic_s, thumbnail_pic_s02, thumbnail_pic_s03, url; String uniquekey; public Data(JSONObject jsonObject) throws Exception{ this.title=jsonObject.getString("title"); this.date=jsonObject.getString("date"); this.author_name=jsonObject.getString("author_name"); this.thumbnail_pic_s=jsonObject.getString("thumbnail_pic_s"); //this.thumbnail_pic_s02=jsonObject.getString("thumbnail_pic_s02"); //this.thumbnail_pic_s03=jsonObject.getString("thumbnail_pic_s03"); this.url=jsonObject.getString("url"); // this.uniquekey=jsonObject.getString("uniquekey"); } //image string, title string, date string,author string,linkaddress string public Data(String thumbnail_pic_s,String title, String date, String author_name, String url) { this.title = title; this.date = date; this.author_name = author_name; this.thumbnail_pic_s = thumbnail_pic_s; this.url = url; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } public String getThumbnail_pic_s() { return thumbnail_pic_s; } public void setThumbnail_pic_s(String thumbnail_pic_s) { this.thumbnail_pic_s = thumbnail_pic_s; } public String getThumbnail_pic_s02() { return thumbnail_pic_s02; } public void setThumbnail_pic_s02(String thumbnail_pic_s02) { this.thumbnail_pic_s02 = thumbnail_pic_s02; } public String getThumbnail_pic_s03() { return thumbnail_pic_s03; } public void setThumbnail_pic_s03(String thumbnail_pic_s03) { this.thumbnail_pic_s03 = thumbnail_pic_s03; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUniquekey() { return uniquekey; } public void setUniquekey(String uniquekey) { this.uniquekey = uniquekey; } @Override public String toString() { return "News{" + "title='" + title + '\'' + ", date='" + date + '\'' + ", author_name='" + author_name + '\'' + ", thumbnail_pic_s='" + thumbnail_pic_s + '\'' + ", thumbnail_pic_s02='" + thumbnail_pic_s02 + '\'' + ", thumbnail_pic_s03='" + thumbnail_pic_s03 + '\'' + ", url='" + url + '\'' + '}'; } }
好了,这样子之后就可以
使用GSON
将原始 服务器的json数据—>HttpResult对象
如果你使用retrofit+rxjava
添加addCallAdapterFactory
Retrofit retrofit = new Retrofit.Builder(). baseUrl("http://v.juhe.cn/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
需要修改借口返回的类型,对应泛型修改HttpResult
package com.example.lihui20.testhttp.service; import com.example.lihui20.testhttp.model.Data; import com.example.lihui20.testhttp.model.HttpResult; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.util.List; import retrofit.http.POST; import retrofit.http.Query; import rx.Observable; /** * Created by lihui20 on 2016/12/6. */ public interface HttpService { /* 请求地址:http://v.juhe.cn/toutiao/index 请求参数:type=shehui&key=9f3097f4cbe47e8abb01ca3b92e49cda 请求方式:GET */ @POST("toutiao/index") // Call<List<Data>> getData(@Query("type") String type, @Query("key") String key); Observable<HttpResult> getData(@Query("type") String type, @Query("key") String key); }
访问的数据类型 对应 HttpResult:
Observable observable = myService.getData(type, "9f3097f4cbe47e8abb01ca3b92e49cda"); //获取Observable对象 observable.subscribeOn(Schedulers.io()) // 网络请求切换在io线程中调用 .unsubscribeOn(Schedulers.io())// 取消网络请求放在io线程 .observeOn(AndroidSchedulers.mainThread())// 观察后放在主线程调用 // .doOnNext(new Action1<List<Data>>() {//1 // @Override // public void call(List<Data> dataList) { // // saveUserInfo(userInfo);//保存用户信息到本地 // Log.d("CustomConverterFactory", "doOnNext call dataList---" + dataList); // Log.d("CustomConverterFactory", "doOnNext call currentThread---" + Thread.currentThread().getName()); // } // }).doOnCompleted(new Action0() { // @Override // public void call() { // Log.d("CustomConverterFactory", "doOnCompleted call currentThread---" + Thread.currentThread().getName()); // } // }) .subscribe( new Subscriber<HttpResult>() {//subscribe 子线程 @Override public void onCompleted() { Log.d("CustomConverterFactory", "onCompleted currentThread---" + Thread.currentThread().getName()); } @Override public void onError(Throwable e) { e.printStackTrace(); Log.d("CustomConverterFactory", "165t:" + e.getMessage()); Message msg = mHandler.obtainMessage(); msg.what = 1; msg.obj = type; mHandler.sendMessage(msg); //请求失败 Log.d("CustomConverterFactory", "onError currentThread---" + Thread.currentThread().getName()); } @Override public void onNext(HttpResult httpResult) { Log.d("CustomConverterFactory", " httpResult getReason---" + httpResult.getReason()); // Result result = httpResult.getResult(); Log.d("CustomConverterFactory", " result---" + result.getStat()); List<Data> list1 = result.getList(); Log.d("CustomConverterFactory", " list1.size()---" + list1.size()); // Log.d("CustomConverterFactory", " httpResult getError_code---" + httpResult.getError_code()); //请求成功 Log.d("CustomConverterFactory", "onNext currentThread---" + Thread.currentThread().getName()); // Utils.resetList(list, dataList);//交换数据 try { Log.d("CustomConverterFactory", " Utils.resetList(list, dataList)---" + list); if (list != null && list.size() > 0 && mHandler != null) { Message msg = mHandler.obtainMessage(); msg.what = 0; msg.obj = list; mHandler.sendMessage(msg); empty.setVisibility(View.GONE); cacheMap.put(type, list); } Log.d("lihui", "159 list---" + list); } catch (Exception e) { Log.d("lihui", "114e---" + e.getMessage()); pullToRefreshGridView.onRefreshComplete(); } } });
好了,就是这样子。注意json格式
原始2个:
[ ….] json数组
{… } json对象
对应json返回写
封装类,有 对象、list等。注意名称和json一致。
大致如此。。。
相关文章推荐
- Android 之 网络访问服务器,解析JSON数据(返回无乱码)
- Android访问网络系列之--服务端返回XML或JSON格式数据,Android 进行解析并显示
- Android访问网络系列之--服务端返回XML或JSON格式数据,Android 进行解析并显示
- Android访问网络:服务端返回XML或JSON格式数据,Android 进行解析并使用ListView显示
- android 客户端访问自己建立的服务器并返回JSON数据进行解析学习
- Android之从网络中获取数据并返回客户端的两种方式:XML格式返回与Json格式返回
- Android下网络请求数据,返回数据显示不全,解析json no value for xxx
- 网络访问之json数据解析
- c# 通过访问URL,获取并解析远程服务端返回的复杂Json数据
- 网络通信框架Volley之二——访问服务器获取Json.xml数据和详细的解析数据
- 客户端使用Ajax访问struts2 , struts2如何返回一个json数据!json-lib与flexjson
- Android中对Json数据解析实例(网络访问的问题)
- iOS- 网络访问JSON数据类型与XML数据类型的实现思路及它们之间的区别
- android访问服务器并解析返回的XML和JSON数据
- Android之从网络中获取数据并返回客户端的两种方式:XML格式返回与Json格式返回
- http 访问网络 返回json 解析json
- iOS- 网络访问JSON数据类型与XML数据类型的实现思路及它们之间的区别
- Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程
- Android异步加载网络数据(PHP做服务端返回的json格式)
- Android之从网络中获取数据并返回客户端的两种方式:XML格式返回与Json格式返回