Retrofit、Okhttp使用小记(cookie,accesstoken,POST
博主在项目中用RxJava也差不多几个月了,但是结合Retrofit使用经验还不是太多。恰好新项目的后台是http+json的,就打算尝试一把。
刚开始由于Retrofit还不太熟,但是后台接口急着测试,所以只好先用okhttp把接口测试成功先。
最最简单的测试方法就是http在线测试啦,相信很多小伙伴都知道啦,不过还是给不知道的小伙伴科普一下吧,http://www.atool.org/httptest.php/
okhttp比较简单,测试登录很快就测试成功了,但是在测试其他获取数据的接口时,遇到了一点小麻烦,因为后台做了cookie验证,需要保存登录时的cookie和登录接口返回的accesstoken才能成功获取到数据。
至于保存cookie这个比较简单,都是借鉴一下前人的经验哈,把第一次请求的cookie信息保存到内存中,之后每次请求都使用相同的cookie请求就可以了。
注意在junit测试的时候如果是异步,还没等到获取网络数据,测试就结束了,此时我们要在最后加上一句代码,让程序等待获取数据,不直接结束。
System.in.read();
先贴一下使用ok实现登录的代码:
public Call UserLogin(String username, String pwd) {
MemoryCookieStore cookieStore = new MemoryCookieStore();
cookieJar = new CookieJarImpl(cookieStore);
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
FormBody formBody = new FormBody.Builder()
.add("KEY", MD5.hexdigest("一个固定的key"))
.add("Action","接口名称")
.add("UserName", MyEncode.encode(username))
.add("PassWord", MyEncode.encode(pwd))
.build();
Request request = new Request.Builder()
.url("baseURL:如:http://www.baidu.com/json/Userservice.ashx")
.post(formBody)
.build();
Call call = client.newCall(request);
return call;
}
其他的就不多说了,就是post的基本使用。
重点是这两句代码:
MemoryCookieStore cookieStore = new MemoryCookieStore();
cookieJar = new CookieJarImpl(cookieStore);
创建一个Cookie仓库,接着创建一个cookieJar、在okhttpClient中吧cookieJar设置进去即可。
以上代码用到三个java类,
CookieStore.java、MemoryCookieStore.java、CookieJarImpl.java 都是直接复制过来用的,是鸿洋封装的okhttpUtils里面的代码~
之后每次访问后台接口都使用相同的cookieJar。
使用okhttp测试接口比较简单,很快就测试好了。但是每次测试都要写一大堆东西,非常麻烦。
再加上本来就是想要熟练一下Retrofit的使用的,之前只用在WebService上,很多使用都不一样,要注意的也不一样。
接下来我们开始改造:
如果接触过一点Retrofit的应该都知道要先写一个IApi接口吧。接口我们都知道,面向接口编程,达到解耦程序的目的。
我们先新建一个IUserApi ,并添加一个登陆方法。
public interface IUserApi {
@POST("UserService.ashx")
Observable<RequestResult<String>> login(
@Query("Action") String action,
@Query("KEY") String key,
@Query("UserName") String username,
@Query("PassWord") String password);
}
看上去应该没啥问题,基本上都是参考网上写的。
接下来是使用。
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(new MyOkHttpClient())
.baseUrl(Dic.BASEURL)
.build();
IUserApi api = retrofit.create(IUserApi.class);
api.login("login","key","fancy","123456")
.subscribe(new ServerSubscriber<String>(iview) {
@Override
public void onMyNext(String accesstoken) {
System.out.println(accesstoken);
});
在junit中测试时,不用加,加了会报错,正式使用的时候可以加上。
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
接下来就是跑junit测试,哎,咋就是登陆失败呢。
看上去明明和okhttp一样啊,用的okhttpClient就是之前的,怎么会有问题呢? 改了半天也没改出什么名堂来~最后决定使出我的终极绝招,HttpLoggingInterceptor
http请求拦截,看看请求过程中有什么不一样。
以下是okhttp方式的日志:
信息:
POST http://www.baidu.com/json/UserService.ashx http/1.1
信息:
KEY=1234353464565&Action=login&UserName=MKs6XgGG7ZJdKMqHI8sYSA%3D%3D%0A&PassWord=cAL%2BvRqMtRI%3D%0A
一下是Retrofit方式的日志:
信息:
--> POST http://www.baidu.com/json/UserService.ashx?Action=userLogin&KEY=1234353464565&UserName=MKs6XgGG7ZJdKMqHI8sYSA%3D%3D%0A&PassWord=cAL%2BvRqMtRI%3D%0A http/1.1
应该一眼就能看出区别了,前者是post到baseurl,参数是表单形式传递的。 而后者是直接连参数一起post过去了。
那我们应该如何修改呢。最开始我也只是随便尝试,修改@Query,试试别的参数,查看了一下@Field(按住ctrl单击跳到对应类),对应的解释是Named pair for a form-encoded request.,感觉应该是这个。
然后把请求接口中的@Query全都替换成了@Field。
又跑了一遍,结果提示必须添加编码,这时候也不知道该如何添加编码,最后就直接百度了。其实只要再接口上添加一个@FormUrlEncoded
注解就可以了。
最终的接口如下:
@FormUrlEncoded
@POST("UserService.ashx")
Observable<RequestResult<String>> UserLogin(
@Field("Action") String action,
@Field("KEY") String key,
@Field("UserName") String username,
@Field("PassWord") String password);
再跑一遍就能够登录成功了。
关于获取数据,测试前需要先登录,然后使用相同的cookie和登录的accesstoken才能够成功获取到数据。
这个就要rxjava来配合了,当然你也可以用okhttp迷之缩进哈,至于代码的可读性和通用性,那就不好说了,谁用谁知道是不?
Retrofit本来就提供了rxjava支持的,所以我们用rxjava来实现线程调度~ !!! 拒绝迷之缩进 !!!
因为Retrofit的创建基本是通用的,就直接封到一个RetrofitUtil.create()方法里面了。
Retrofit retrofit = RetrofitUtil.create("");
IUserApi api = retrofit.create(IUserApi.class);
TestApi.getAccesstoken()
.flatMap(new Func1<RequestResult<String>, Observable<? extends String>>() {
@Override
public Observable<? extends String> call(RequestResult<String> stringRequestResult) {
return api.getInfo("GetInfo", Dic.key, stringRequestResult.getAccesstoken());
}
})
.subscribe(new ServerSubscriber<String>() {
@Override
public void onNext(String s) {
System.out.println(s);
}
});
一个flatMap就解决问题啦,是不是非常简单,用lambda格式化一下,会更加简洁。
TestApi.getAccesstoken()
.flatMap(stringRequestResult -> api.getInfo("GetInfo", Dic.key, stringRequestResult.getAccesstoken()))
.subscribe(new ServerSubscriber<String>() {
@Override
public void onNext(String s) {
System.out.println(s);
}
});
经过以上步骤基本上把okhttp改造成了Retrofit+Rx了。虽然暂时还看不出多大的优势,似乎只有在最后测试时获取token再获取数据那里稍微简单一点,但是,在正式使用的时候token不是第一次请求就保存下来了么,这种形式应该用不上吧。
没错,在以上场景只是测试方便,在正式使用的时候并用不上。
但是接下来的需求,RxJava应该能够让你心服口服。
有点累,下篇博客再更吧。
Retrofit、Okhttp使用小记(cookie,accesstoken,POST的更多相关文章
- Android okHttp网络请求之Retrofit+Okhttp+RxJava组合
前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...
- RxJava+Retrofit+OkHttp,一步一步封装网络框架;
使用RxJava+Retrofit+OkHttp,首先在build.gradle添加: compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com ...
- Retrofit/OkHttp API接口加固技术实践(下)
作者/Tamic http://blog.csdn.net/sk719887916/article/details/65448628 imageMogr2/auto-orient/strip%7Cim ...
- Retrofit+Okhttp+RxJava打造网络请求之Post
之前一直在准备Android培训的事情,所幸的是终于完事啦,在这过程中真的发现了自身无论从沟通能力还是技术能力上很多的不足,就用一句 路漫漫其修远兮,吾将上下而求索 来勉励自己吧.之前也在项目上用上O ...
- 「2020 新手必备 」极速入门 Retrofit + OkHttp 网络框架到实战,这一篇就够了!
老生常谈 什么是 Retrofit ? Retrofit 早已不是什么新技术了,想必看到这篇博客的大家都早已熟知,这里就不啰嗦了,简单介绍下: Retrofit 是一个针对 Java 和 Androi ...
- spring-cloud-square源码速读(retrofit + okhttp篇)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos spring-cloud-square系列文章 五分钟 ...
- android 中对于采用okhttp时获取cookie并放入webview实现跳过登陆显示页面的功能
最近项目需要将网页的一些信息展示到app当中,由于采用的是okhttp进行网络的访问,并采用了cookie对于每次的访问请求都做了验证,所以在加入webview显示网页的时候会需要进行一下验证,为了跳 ...
- Retrofit/Okhttp API接口加固技术实践(上)
作者:Tamic 地址:http://blog.csdn.net/sk719887916/article/details/61914609 写这篇文章,我纠结了非常久,究竟是属于app安全系列,还是属 ...
- retrofit okhttp RxJava bk Gson Lambda 综合示例【配置】
项目地址:https://github.com/baiqiantao/retrofit2_okhttp3_RxJava_butterknife.git <uses-permission andr ...
随机推荐
- ExtJS梦想之旅(八)--GridPanel和EditorGridPanel的使用
表格在web开发中会经常被使用到,是一种非常重要的组件,因此ExtJS在这方面做得也很出色,在这里也作为一个重点的组件来和大家分享,共同探讨一下. Ext.grid.GridPanel此类系基于Gri ...
- 【deep learning学习笔记】注释yusugomori的DA代码 --- dA.h
DA就是“Denoising Autoencoders”的缩写.继续给yusugomori做注释,边注释边学习.看了一些DA的材料,基本上都在前面“转载”了.学习中间总有个疑问:DA和RBM到底啥区别 ...
- 读书笔记,《Java 8实战》,第四章,引入流
集合是Java中使用最多的API,但集合操作却远远算不上完美.主要表现在两点, 第一,集合不能让我们像数据库的SQL语言一样用申明式的语言指定操作: 第二,现在的集合API无法让我们 ...
- OC-字符串中大小写字母转换
一般语言中的大小写转换都会提供的有默认的函数,不过闲来无事,简单的模仿实现了一下: 系统中默认的大小写转换: NSString *name=@"博客园-FlyElephant"; ...
- 对Attention is all you need 的理解
https://blog.csdn.net/mijiaoxiaosan/article/details/73251443 本文参考的原始论文地址:https://arxiv.org/abs/1706. ...
- RabbitMQ的应用场景以及基本原理介绍 【转】
http://blog.csdn.net/whoamiyang/article/details/54954780 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 背景 应用 ...
- w3cscholl的在线代码编辑工具2
https://www.w3cschool.cn/tryrun/runcode?lang=c
- (转)NGUI中深度depth和z轴关系
先列出转载链接: http://game.ceeger.com/forum/read.php?tid=8917 转载原文: 问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖 ...
- 测试数据——有效范围(2)
测试数据库搞好,学习了一下逾期率的官方定义: • 对于某支标,如果某一期没有正常还款,则悲观逾期率=所有未还本金/借款本金: • 对于一批标,悲观逾期率=当前逾期标的所有未还本金/借款本金: • 以3 ...
- KVM 虚拟化技术
1.1 前言 1.1.1 什么是虚拟化? 在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU.内存.磁盘空间.网络适配器 ...