39. 网络加载框架Retrofit中的转换器和适配器

39. 网络加载框架Retrofit其他
39.1 Retrofit中的转换器
在接到服务器响应后,目前无论是OKhttp还是Retrofit都只能接收到String字符串类型的数据,在实际开发中,通常需要对字符串进行解析将其转变为一个Java Bean对象。

Retrofit提供了多个转换器使得响应能够自动完成数据的转换。

json解析:

添加依赖

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

在这里插入图片描述

使用“玩安卓”的开放API

定义接口

在这里插入图片描述

定义接口

package com.dingjiaxiong.myretrofit;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;

public interface WanAndroidService {

    @POST("user/login")
    @FormUrlEncoded
    Call<ResponseBody> login(@Field("username") String username,@Field("password") String pwd);

}



编写测试

package com.dingjiaxiong.myretrofit;

import org.junit.Test;

import java.io.IOException;

import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;

public class WanAndroidUnitTest {

    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.wanandroid.com/").build();
    WanAndroidService wanAndroidService = retrofit.create(WanAndroidService.class);

    @Test
    public void loginTest() throws IOException {
        Response<ResponseBody> response = wanAndroidService.login("dingjiaxiong", "200039").execute();
        System.out.println(response.body().string());
    }
}

运行

在这里插入图片描述

现在想把这一段字符串转成一个Java Bean对象

导入Gson库依赖

在这里插入图片描述

使用这个工具

https://www.bejson.com/

查看一下返回数据的格式

在这里插入图片描述

使用网站工具 → Json生成java类

在这里插入图片描述

修改类名和包名

在这里插入图片描述

在这里插入图片描述

直接复制到项目中

在这里插入图片描述

将response转换为对象

在这里插入图片描述

在这里插入图片描述

可以看到生成成功了,给类加上打印方法

在这里插入图片描述

再次运行

在这里插入图片描述

成功

以上都是 自己【手动】完成的反序列化。

接下来直接使用转换器完成

复制一个接口文件

在这里插入图片描述

将类型直接设置成Java Bean

在这里插入图片描述

并在测试中添加转换器

Retrofit retrofi2 = new Retrofit.Builder().baseUrl("https://www.wanandroid.com/")
        .addConverterFactory(GsonConverterFactory.create()) // 添加转换器
        .build();
WanAndroidService2 wanAndroidService2 = retrofit.create(WanAndroidService2.class);

@Test
public void loginConvertTest() throws IOException {
    Call<BaseResponse> call = wanAndroidService2.login("dingjiaxiong", "200039");
    Response<BaseResponse> response = call.execute();
    BaseResponse baseResponse = response.body();
    System.out.println(baseResponse);
}

在这里插入图片描述

运行

在这里插入图片描述

报错了,啊这,看下代码

在这里插入图片描述

这儿写错了

OK,再次运行

在这里插入图片描述

和手动转换结果一致。

39.2 Retrofit的嵌套请求
在实际开发中,可能会存在:需要先请求A接口,再请求B接口的情况,比如需要请求获取收藏列表文章,但是需要先登录拿到Cookie才能请求收藏文章列表接口。

此时请求就有了先后顺序。

这样会使得代码很冗长

39.3 Retrofit中的适配器
Retrofit的接口方法的返回类型必须是Call,如果能够将Call改为RxJava中的Observable,对于嵌套的情况,就能得到非常方便、优雅的解决。

→ 这就是适配器。

添加依赖

implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

在这里插入图片描述

同步

修改接口

登录接口

@POST("user/login")
@FormUrlEncoded
Flowable<BaseResponse> login2(@Field("username") String username, @Field("password") String pwd);

在这里插入图片描述

获取文章列表接口

@GET("lg/collect/list/{pageNum}/json")
Flowable<ResponseBody> getArticle(@Path("pageNum") int pageNum);

在这里插入图片描述

使用适配器

Map<String,List<Cookie>> cookies = new HashMap<>();
Retrofit retrofit3 = new Retrofit.Builder()
        .baseUrl("https://www.wanandroid.com/")
        .callFactory(new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> list) {
                        cookies.put(url.host(),list);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url) {
                        List<Cookie> cookies = WanAndroidUnitTest.this.cookies.get(url.host());
                        return cookies == null ? new ArrayList<>() : cookies;
                    }
                })
                .build())
        .addConverterFactory(GsonConverterFactory.create()) // 添加转换器
        //添加适配器
        .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
        .build();
WanAndroidService2 wanAndroidService3 = retrofit3.create(WanAndroidService2.class);

@Test
public void rxjavaTest(){
    wanAndroidService3.login2("dingjiaxiong","200039")
            .flatMap(new Function<BaseResponse, Publisher<ResponseBody>>() {
                @Override
                public Publisher<ResponseBody> apply(BaseResponse baseResponse) throws Throwable {
                    return wanAndroidService3.getArticle(0);
                }
            })
            .observeOn(Schedulers.io())
            .subscribeOn(Schedulers.newThread())
            .subscribe(new Consumer<ResponseBody>() {
                @Override
                public void accept(ResponseBody responseBody) throws Throwable {
                    System.out.println(responseBody.string());
                }
            });
    while (true){}
}

在这里插入图片描述

成功根据cookie拿到结果。

posted @ 2022-09-19 08:49  随遇而安==  阅读(61)  评论(0编辑  收藏  举报