在使用retrofit之前,你需要导入retrofit gsonconverter这些库。详情可以查看相关资料。https://github.com/square/retrofit ,现在出到最新的版本是2.4.0.
在retrofit之前都是用okhttp直接请求,比如
val client = OkHttpClient()
val body=FormBody.Builder()
body.add("key","value")
val request = Request.Builder()
.url("www.github.com")
.post(body.build())
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
}
override fun onResponse(call: Call?, response: Response?) {
}
})
到了retrofit ,更加简单和gson rxjava 配合使用。
GET请求
在retrofit使用过程中,你需要定义一个接口类,比如:
interface MainService {
@GET("/v1/home")
fun getMain(@Query("offset") offset: Int, @Query("limit") limit: Int): Observable<MainList>
}
可以看到有个 getMain 方法,他通过 @GET 注解标记为 get 请求,@GET里面的值个 baseUrl 组成完整路径,baseUrl 在实例化 Retrofit 时赋值。
val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(httpInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
var retrofit = Retrofit.Builder()
.baseUrl(RanUrl.URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return retrofit.create(MainService::class.java);
可以看出构建 OkHttpClient 或者是 Retrofit 的实例都用上了构造者模式,
指定了 url ,okhttpclient 和转化工厂。
最后通过 retrofit.create 返回 MainService 对象,然后调用 MainService 里面的方法
当你的请求后返回的是不是 json 格式的字符串,你也可以注册 converter-scalars 来获取到字符串。
GET请求动态url
当使用 restful 风格的 url ,就会遇到 /user/apple 这样子的请求地址,这时候你可以
interface MainService {
@GET("user/{username}")
fun user(@PATH("username") username:String):Observable<Response>
}
可以看到我们定义了一个 user 方法 接受一个 username 的参数,然后把 username 赋值到地址上,最后你会看到请求的是 baseurl/user/apple , 这个地址。
GET请求键值对
当你要从后台获取数据,通常要指定返回 pagesize ,第几页,�筛选key这些参数,比如:
interface MainService {
@GET("/user")
fun user(@Query("pageSize") pageSize:String):Observable<Response>
}
我们可以看到最后请求的地址是 baseurl/user?pageSize=1这样子。会把key value都放在地址上。而path 只会把值放在地址上。
POST一下
一般我们以表单方式 post 键值对到后台,这时候就用到 @FormUrlEncoded ,比如:
@POST("/user")
@FormUrlEncoded
fun user(@FieldMap option : HashMap<String, String> ):Observable<Response>
使用的时候你要创建一个 HashMap,key 和 value 分别对应 后台需要的key 和 value。
POST一个JSON字符串
当你要post一个�json格式的字符串到服务器时,�就要用到@Body标注,
@POST("/user")
fun user(@Body user : User) : Observable<Response>
这时候创建一个User的实体类,传入user方法即可。
POST一个文件
@Multipart
@POST("/user")
fun user(@Part photo : MultipartBody.Part ,@Part("username") username : RequestBody ):Observable<Response>
这时候是上传 username 的键值对和一个图片文件 MultipartBody。@Multipart 可以上传多个 @Part 文件和键值对。
使用的时候用 ,键值对用 RequestBody 包一层,图片先用 RequestBody 包一层,再用 MultiRequestBody.Part 包一层。
val file = new File(filePath)
val photoRequestBody = RequestBody.create(MediaType.parse("image/png"), file)
val photo = MultipartBody.Part.createFormData("photos", "icon.png", photoRequestBody)
val username = RquestBody.create(null, "name")
var response = user(photo,username)
POST一堆文件
比如你今天发个朋友圈就用到这个上传一堆文件的方法了。
@Multipart
@POST("/user")
fun user(@PartMap params : Map<String,RequestBody> ,@Part("username") username : RequestBody ): Observable<Response>
这时候用到一个新注解@PartMap ,传入的是map类型,key是服务器接受的key value是包着文件的requestbody。
val file = File("filepath")
val photo = RequestBody.create(MediaType.parse("image/png"), file)
val map = HashMap<String, RequestBody>()
map["images\";filename=\"image.png"] = photo
map["desc"] = RequestBody.create(null, "desc")
val response = user(map,RequestBody.create(null, "name"))
以上。
网友评论