1、
在上个头条新闻的项目中我解析的数据是聚合数据返回的
{
"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一致。
大致如此。。。