111
社区成员




这个作业属于哪个课程 | 2401_CS_SE_FZU |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
这个作业的目标 | 本学期软件工程实践以及个人掌握的技术的总结 |
其他参考文献 | 探索Android Studio , Square Retrofit官方文档 |
在build.gradle.kts文件中添加Retrofit依赖:
dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.9.0")
}
我们定义了ArticleApiService接口,用于与文章相关的RESTful API交互。该接口包含获取、删除、更新、添加文章及其图片的方法,使用Call来进行异步调用:
interface ArticleApiService {
// 获取所有文章
@GET("article/getAllArticle")
fun getAllArticles(): Call<ArticleResponse>
// 删除文章
@DELETE("article/{id}/deleteArticle")
fun deleteArticle(@Path("id") articleId: Int): Call<DeleteArticleResponse>
// 根据分类获取文章列表
@GET("article/getArticlesByClass")
fun getArticleList(@Query("articleClass") data: String): Call<ArticleResponse>
// 修改文章
@PUT("article/{id}/updateArticle")
fun updateArticle(
@Path("id") id: Int,
@Body articleUpdateRequest: ArticleUpdateRequest
): Call<UpdateArticleResponse>
// 添加文章
@POST("article/addArticle")
fun addArticle(@Body article: ArticleRequest): Call<PostArticleResponse>
// 为文章添加媒体文件(图片)
@Multipart
@POST("article/{id}/addPicture")
fun addPicture(
@Path("id") articleId: Int,
@Part filePart: MultipartBody.Part
): Call<PostArticlePictureResponse>
// 删除图片
@DELETE("article/deletePicture")
fun deletePicture(@Query("url") url: String): Call<PostArticlePictureResponse>
// 获取文章的所有图片
@GET("/article/{id}/getPictures")
fun getArticlePictures(@Path("id") articleId: Int): Call<GetPicturesResponse>
// 添加浏览历史
@POST("/article/{id}/addHistory")
fun addHistory(@Path("id") articleId: Int): Call<PostArticleHistory>
}
过程包括设置Base URL、配置Gson转换器、集成OkHttp客户端以增强功能(如超时设置和添加请求头),并确保所有网络请求都携带有效的认证令牌。
// 获取用户认证令牌
val token: String = TokenManager.getToken(App.INSTANCE) ?: ""
// 创建 Retrofit 实例
val retrofit = Retrofit.Builder()
.baseUrl("http://113.44.68.6:8080/") // 使用实际的基地址
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 作为 JSON 转换器
.client(
OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
.writeTimeout(30, TimeUnit.SECONDS) // 设置写入超时时间
.readTimeout(30, TimeUnit.SECONDS) // 设置读取超时时间
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $token") // 在请求中添加 Authorization 头
.build()
chain.proceed(request)
}
.build()
)
.build()
// 创建 API 服务接口的实例
val articleApiService = retrofit.create(ArticleApiService::class.java)
使用Retrofit的enqueue方法发起异步请求,并通过回调处理成功和失败的情况
fun fetchArticles(callback: (List<Article>) -> Unit, onError: (String) -> Unit) {
articleApi.getAllArticles().enqueue(object : Callback<ArticleResponse> {
override fun onResponse(
call: Call<ArticleResponse>,
response: Response<ArticleResponse>
) {
if (response.isSuccessful && response.body() != null) {
callback(response.body()!!.data) // 将数据通过回调返回
} else {
onError("Error: ${response.message()}")
}
}
override fun onFailure(call: Call<ArticleResponse>, t: Throwable) {
onError("Network Error: ${t.message}")
}
})
}
使用Gson转换器工厂自动解析JSON响应为Kotlin数据类。确保数据类是可序列化的
data class ArticleRequest(
val userId: Int,
val title: String,
val content: String,
val datetime: String,
val articleClass: String
)
override fun onResponse(
call: Call<ArticleResponse>,
response: Response<ArticleResponse>
) {
if (response.isSuccessful && response.body() != null) {
callback(response.body()!!.data) // 将数据通过回调返回
} else {
onError("Error: ${response.message()}") // 处理HTTP请求失败的情况
}
}
override fun onFailure(call: Call<ArticleResponse>, t: Throwable) {
onError("Network Error: ${t.message}") // 处理网络异常
}
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
if (token.isEmpty()) {
// 可选:提示用户登录或刷新令牌
}
chain.proceed(request)
}
2. 实现重试机制,在首次请求失败后自动重试几次。
示例:
OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS) // 增加读取超时时间
.writeTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build()
1. 在onResponse回调中检查具体的HTTP状态码,并根据情况显示适当的错误信息。
2. 提供更友好的用户反馈,例如提示用户检查网络连接或重新登录。
示例:
override fun onResponse(
call: Call<ArticleResponse>,
response: Response<ArticleResponse>
) {
if (response.isSuccessful && response.body() != null) {
callback(response.body()!!.data)
} else {
val errorMessage = when (response.code()) {
401 -> "Unauthorized. Please log in again."
404 -> "Resource not found."
500 -> "Server error. Please try again later."
else -> "Error: ${response.message()}"
}
Log.e("API Error", "HTTP error occurred: $errorMessage")
onError(errorMessage)
}
}
通过深入学习Retrofit及其与Kotlin的结合使用,我掌握了如何在Android应用中高效地进行RESTful API通信。这不仅提高了我的开发效率,还增强了我对网络编程的理解。面对挑战时,不断探索和尝试新方法是解决问题的关键。协程的支持使得异步编程更加直观和简洁,极大提升了用户体验。