androidretrofit
‘壹’ Android retrofit 注解@QueryMap和@Body的区别
如果你的项目是采用POST请求方式,不管是使用实体类还是使用HashMap最好采用@Body注解。虽然你使用QueryMap可能也不会有什么问题(PS:这种共用的情况只适用于POST请求,GET请求不能使用@Body注解,否则会报错)。
使用retrofit这样框架快一年了,以前使用它传递参数时都是用@QueryMap注解传递,虽然知道这样不是很好,但是当时换框架的时候看到工作量太大就没有换成实体类形式了,之前的使用方式如下图:
2.由于最近在研究java后台,搭建了一个SSM框架想测试一下;因为之前以为HashMap只能采用这种方式传递,在今天的测试中发现并不是,其实使用HashMap同样可以采用@Body注解,而且@QueryMap跟@Body的区别非常大,先看按之前的方式使用@QueryMa
3.上面是android的代码,使用了RxJava。在来看java后台的:
4.使用HttpServletRequest来接收是没有问题的,但是如果后台使用@RequestBody来接收参数就没法接收到了,而且连请求都没接收到:
5.下面我们来看一下,androidStudio打印的日志,发现后台返回了400,并且发现参数拼接到连接后面了,这不是GET的传递参数的方式吗?但是我明明是POST注解请求:
6.我点击注解看了下源码,看到下面的注释,第一句的大意就是说:会把key和value拼接到url后面,所以才会出现刚刚日志中那种情况,而且看注释都是在讲GET请求下的使用,并没有POST的使用介绍,所以我感觉这个注解是主要为GET请求准备的:
7.在来看@Body,先看源码吧 ,注释的大体意思是:使用这个注解可以把参数放到请求体中,适用于 POST/PUT请求:
8.然后再看使用方式,和@QueryMap 一样的,而且它可以使用实体类,QueryMap 是不能注解实体类的:
9.在看打印的日志:
10.从日志看出来,这才是POST请求参数参数的方式。
总结一下:@QueryMap注解会把参数拼接到url后面,所以它适用于GET请求;@Body会把参数放到请求体中,所以适用于POST请求。
‘贰’ Android上使用retrofit+okhttp时token失效的处理方案
提前声明,以下提到的方案并没有去验证过可行性,只是记录一下,未来需要用到的时候,在仔细验证一下。
一般情况下,各个公司的移动端关于登录令牌(token)的设定都各不相同。
可先参考这个链接: https://www.hu.com/question/30267006
了解一下,本文大概想说什么。
有些公司服务端是按照oauth设计,比较标准规范,但是有些公司有自己的特定业务,未完全按照oauth来设计。基于本公司的业务逻辑,考虑了一下登录的逻辑以及token的设计。
思路如下:
token即验证令牌,每次请求都带上,refreshToken用来刷新token的,每次请求可以不带上,但是要放在移动端保存。
1.通过username,password获取token和refreshToken
2.token的有效期为2小时,refreshToken的有效期为15天
3.如果服务器端判断token过期,而refreshToken未过期,就返回错误码给客户端,则客户端通过一个特定的接口传入refreshToken参数获取新的token和refreshToken
4.如果连续15天未使用app或者用户修改了密码,则表示refreshToken过期了,则跳到登录界面,重新登录获取token和refreshToken
基于上面的思路,如果服务端走rest风格,移动端(Android)采用retrofit(v2.0+)+okhttp(v2.7.0+)网络请求框架。那么当token过期了,Android端应该如何处理呢?
通过okhttp提供的Authenticator接口,相关资料 点击这里 ,但是查看okhttp的源码会发现,只有返回HTTP的状态码为401时,才会使用Authenticator接口,如果服务端设计规范,可以尝试如下方法。
实现Authenticator接口
然后给添加给OkHttpClient
第一种方案就这样了。
但是,万事不会尽如人意,如果服务端在token过期的时候,不给返回401的HTTP状态码,而是返回如下类型的数据,叫你根据code判断。
这里要清楚HTTP状态码是指200,404,401这些,而上面的数据中的code是自定义的。如果在token过期时,服务端返回的是如上类型的数据,那么第一种方案就行不通。
通过okhttp的拦截器,okhttp 2.2.0 以后提供了拦截器的功能,相关介绍 点击这里
然后给okhttp设置拦截器
第二种方案的思路是通过拦截返回的数据,判断token是否过期,如果过期则进行一次刷新token的操作。
上面2种方案都没有进行实际验证过,希望以后有机会能验证。
完。。。
‘叁’ 【Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...
对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了。
下面分为GET、POST、DELETE还有PUT的请求,说明@Path、@Query、@QueryMap、@Body、@Field的用法。
http://102.10.10.132/api/News
http://102.10.10.132/api/News/1
http://102.10.10.132/api/News/ {资讯id}
或
http://102.10.10.132/api/News/1/ 类型1
http://102.10.10.132/api/News/ {资讯id}/{类型}
http://102.10.10.132/api/News?newsId=1
http://102.10.10.132/api/News?newsId= {资讯id}
或
http://102.10.10.132/api/News?newsId=1&type= 类型1
http://102.10.10.132/api/News?newsId= {资讯id}&type={类型}
http://102.10.10.132/api/News?newsId=1&type= 类型1...
http://102.10.10.132/api/News?newsId= {资讯id}&type={类型}...
也可以
http://102.10.10.132/api/Comments/1
http://102.10.10.132/api/Comments/ {newsId}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token}
http://102.10.10.132/api/Comments/1
http://102.10.10.132/api/Comments/ {commentId}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {commentId}?access_token={access_token}
http://102.10.10.132/api/Comments
CommentBody :需要提交的内容,与 Post 中的 Body 相同
http://102.10.10.132/api/Accounts/1
http://102.10.10.132/api/Accounts/ {accountId}
@Path:所有在网址中的参数(URL的问号前面),如:
http://102.10.10.132/api/Accounts/ {accountId}
@Query:URL问号后面的参数,如:
http://102.10.10.132/api/Comments?access_token= {access_token}
@QueryMap:相当于多个@Query
@Field:用于POST请求,提交单个数据
@Body:相当于多个@Field,以对象的形式提交
Tips
‘肆’ 在Android中使用retrofit时,怎样获取响应的头信息
获取方法
有两种获取Response Headers的方法
直接在定义接口是让接口返回Retrofit的Response对象,
在Response对象中可以获取到Headers
Interceptor必须在OkHttpClient构建时加入,
OKHttpClient的interceptors()方法返回的是一个不可编辑的列表,
如果对其进行修改操作,会产生UnSupportedOperationException。
‘伍’ 在Android中使用retrofit时,怎样获取响应的头信息
有两种获取Response Headers(即响应的头信息)的方法,第一种是直接在定义接口是让接口返回Retrofit的Response对象,在Response对象中可以获取到Headers。在构建Retrofit的APIService,在OkHttpClient中加入Interceptor,用以拦截请求和响应获取请求头和响应头。此方法可用于Retrofit2和OKHttp3.