https://square.github.io/retrofit/
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// 或
// implementation 'com.squareup.retrofit2:retrofit:(insert latest version)'
// gson 解析数据,直接转换成需要的实体类或其他类型(可以不添加)
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
// 数据请求
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
val baseurl = "https://www.wanandroid.com"
val username = "bin"
val password = "123456"
interface Api{
// 登陆
@FormUrlEncoded
@POST("/user/login")
fun login(@Field("username") username:String, @Field("password") password:String) : Call<WanAndroidResponse<WanAndroidUser>>
// 首页文章列表
@GET("/article/list/{page}/json")
fun homeArticleList(@Path("page") page:Int) : Call<WanAndroidResponse<ArticleList>>
}
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(baseurl)
.addConverterFactory(GsonConverterFactory.create())
.build()
var mApi: Api = retrofit.create(Api::class.java)
mApi.homeArticleList(0).also {
it.enqueue(object : Callback<WanAndroidResponse<ArticleList>> {
override fun onFailure(
call: Call<WanAndroidResponse<ArticleList>>?,
t: Throwable?
) {
Log.e(TAG, "getHomeArticleList onFailure:\n ${t.toString()}\n${call.toString()}" )
}
override fun onResponse(
call: Call<WanAndroidResponse<ArticleList>>?,
response: Response<WanAndroidResponse<ArticleList>>?
) {
Log.e(TAG, "getHomeArticleList onResponse: ${response!!.body().toString()}" )
}
})
}
mApi.login(username, password).also {
it.enqueue(object : Callback<WanAndroidResponse<WanAndroidUser>> {
override fun onFailure(call: Call<WanAndroidResponse<WanAndroidUser>>, t: Throwable) {
Log.e(TAG, "login onFailure:\n ${t.toString()}\n${call.toString()}" )
}
override fun onResponse(
call: Call<WanAndroidResponse<WanAndroidUser>>,
response: Response<WanAndroidResponse<WanAndroidUser>>
) {
Log.e(TAG, "login onResponse: ${response.body().toString()}" )
Log.e(TAG, "onResponse: ${response.headers()}" )
cookieList = response.headers().values("Set-Cookie")
Log.e(TAG, "onResponse: ${response.headers().values("Set-Cookie")}\n${cookieList.size}" )
}
})
}
@Multipart
@POST("home/upload-image")
Call<PictureBean> setHttpPortrait(@Part MultipartBody.Part part);
private void setHttpPortrait(final String name, final String strPath) {//name:参数名称;strPath:图片路径
File file = new File(strPath);
RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part imageBodyPart = MultipartBody.Part.createFormData(name, file.getName(), imageBody);
Call<PictureBean> repos = xxx.setHttpPortrait(imageBodyPart);
repos.enqueue(new Callback<PictureBean>() {
@Override
public void onResponse(Call<PictureBean> call, Response<PictureBean> response) {
try {
if (response.body().isOk()) {//请求成功
//返回数据处理
} else {
//图片上传失败
}
} catch (Exception e) {
//返回数据异常
}
}
@Override
public void onFailure(Call<PictureBean> call, Throwable t) {
//请求异常
}
});
}
@Multipart
@POST("home/upload-image")//多张上传图片
Call<PictureBean> setHttpDataPortrait(@Part List file);
private void setHttpPortrait(final String name, final List<String> paths) {
showLoading();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (String path : paths) {
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"), file);
builder.addFormDataPart("files", file.getName(), requestBody);
}
List parts = builder.build().parts();
Call<PictureBean> repos = xxx.setHttpDataPortrait(parts);
repos.enqueue(new Callback<PictureBean>() {
@Override
public void onResponse(Call<PictureBean> call, Response<PictureBean> response) {
try {
if (response.body().isOk()) {
//返回数据处理
} else {
//图片上传失败
}
} catch (Exception e) {
//返回数据异常
}
}
@Override
public void onFailure(Call<PictureBean> call, Throwable t) {
//请求异常
}
});
}
mApi.xxx().enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
// 请求成功,进行后续处理
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
// 请求失败,进行后续处理
}
})
@Headers
添加请求头(固定的请求头)
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@HeaderMap
添加请求头(不固定的请求头)
@GET("user")
Call<User> getUser(@HeaderMap Map<String, String> headers)
@Header
添加单个请求头(不固定的请求头)
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
@Body
用于非表单请求体(传实体类对象或其他自己需要的类型)
@POST("users/new")
Call<User> createUser(@Body User user);
@POST("auth/guest")
Call<BaseResponse<TokenInfo>> guest(@Body RequestBody requestBody);
@Field
向 post 表单传入键值对
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@FieldMap
向 post 表单传入多个键值对
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@FieldMap Map<String, String> fields);
@Part
向 post 表单传入键值对(需要上传文件的场景)
@Multipart
@POST("/")
Call<ResponseBody> example(
@Part("description") String description,
@Part(value = "image", encoding = "8-bit") RequestBody image);
@Multipart
@POST("home/upload-image")
Call<PictureBean> setHttpPortrait(@Part MultipartBody.Part part);
@PartMap
向 post 表单传入多个键值对(需要上传文件的场景)
@Multipart
@POST("/upload")
Call<ResponseBody> upload(
@Part("file") RequestBody file,
@PartMap Map<String, RequestBody> params);
@Multipart
@POST("home/upload-image")//多张上传图片
Call<PictureBean> setHttpDataPortrait(@Part List file);
@Query
向 get 请求传入参数及对应的值
@GET("/friends")
Call<ResponseBody> friends(@Query("page") int page);
@QueryMap
向 get 请求传入多个参数及对应的值
@GET("/friends")
Call<ResponseBody> friends(@QueryMap Map<String, String> filters);
@Path
向 get 请求传入链接的缺省值
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);