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

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一致。
大致如此。。。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值