您的位置:首页 > 理论基础 > 计算机网络

在retrofit访问网络返回json数据添加解析器

2017-06-10 18:05 381 查看
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一致。

大致如此。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  json retrofit
相关文章推荐