使用Retrofit上传文件至服务器及Android端按指定格式发起Retrofit请求
嘿,这两个问题都是Android开发里用Retrofit做文件上传的常见场景,我给你一步步捋清楚:
1. 如何使用Retrofit实现文件上传至服务器
第一步:添加必要依赖
先在Module级的build.gradle里引入Retrofit及相关依赖,确保能处理文件上传和JSON解析:implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:okhttp:4.9.3' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' // 可选,用来查看请求日志,方便调试第二步:定义Retrofit上传接口
文件上传必须用@Multipart注解标记接口方法,再用@Part声明文件和其他参数。举两个常见场景:
场景1:仅上传单个文件interface FileUploadService { @Multipart @POST("upload") // 替换成你的服务器上传接口路径 suspend fun uploadSingleFile( @Part file: MultipartBody.Part ): Response<UploadResult> // UploadResult是你自定义的响应实体类 }场景2:上传文件同时携带其他参数(比如用户ID、文件名)
@Multipart @POST("upload") suspend fun uploadFileWithParams( @Part("userId") userId: RequestBody, @Part("fileName") fileName: RequestBody, @Part file: MultipartBody.Part ): Response<UploadResult>第三步:构建请求并发起调用
把本地文件转换成MultipartBody.Part,再在协程里发起请求(Android推荐用协程处理网络请求):// 1. 准备要上传的文件 val targetFile = File(getExternalFilesDir(null), "test.pdf") val fileRequestBody = RequestBody.create(MediaType.parse("application/pdf"), targetFile) val filePart = MultipartBody.Part.createFormData("file", targetFile.name, fileRequestBody) // 2. 准备其他参数(如果需要) val userIdBody = RequestBody.create(MediaType.parse("text/plain"), "67890") val fileNameBody = RequestBody.create(MediaType.parse("text/plain"), "我的测试文档.pdf") // 3. 创建Retrofit实例 val retrofit = Retrofit.Builder() .baseUrl("https://your-server-domain.com/") // 替换成你的服务器基础地址 .addConverterFactory(GsonConverterFactory.create()) .build() // 4. 在协程中发起请求 lifecycleScope.launch { try { val service = retrofit.create(FileUploadService::class.java) val response = service.uploadFileWithParams(userIdBody, fileNameBody, filePart) if (response.isSuccessful) { // 上传成功,处理返回结果 val result = response.body() } else { // 上传失败,处理错误信息 val errorMsg = response.errorBody()?.string() } } catch (e: Exception) { // 处理网络异常(比如无网、超时) e.printStackTrace() } }
2. Android平台中,匹配指定请求格式的Retrofit请求实现
假设你提到的服务器请求格式是multipart/form-data混合普通参数、JSON对象和文件的常见场景(比如要求某个字段是JSON结构,同时上传文件),我给你对应实现方案:
第一步:先明确请求结构(模拟示例)
假设服务器要求的请求体如下:userId: 字符串类型(普通参数)userInfo: JSON对象(包含name、phone、address字段)attachment: 文件类型(比如文档或图片)
第二步:定义适配的Retrofit接口
对于JSON类型的参数,需要把它封装成RequestBody并指定媒体类型为application/json:interface CustomFormatUploadService { @Multipart @POST("custom-upload") // 替换成你的接口路径 suspend fun uploadWithCustomFormat( @Part("userId") userId: RequestBody, @Part("userInfo") userInfo: RequestBody, @Part attachment: MultipartBody.Part ): Response<UploadResult> }第三步:构建参数并发起请求
把JSON对象转成字符串后封装成RequestBody,同时处理文件和普通参数:// 1. 准备JSON参数 val userInfo = UserInfo("李四", "138xxxx1234", "北京市朝阳区") // 自定义数据类 val gson = Gson() val userInfoJson = gson.toJson(userInfo) val userInfoBody = RequestBody.create(MediaType.parse("application/json"), userInfoJson) // 2. 准备普通参数 val userIdBody = RequestBody.create(MediaType.parse("text/plain"), "67890") // 3. 准备上传文件 val attachmentFile = File(getExternalFilesDir(null), "简历.docx") val attachmentBody = RequestBody.create(MediaType.parse("application/vnd.openxmlformats-officedocument.wordprocessingml.document"), attachmentFile) val attachmentPart = MultipartBody.Part.createFormData("attachment", attachmentFile.name, attachmentBody) // 4. 发起请求 lifecycleScope.launch { try { val retrofit = Retrofit.Builder() .baseUrl("https://your-server-domain.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val service = retrofit.create(CustomFormatUploadService::class.java) val response = service.uploadWithCustomFormat(userIdBody, userInfoBody, attachmentPart) if (response.isSuccessful) { // 处理成功逻辑 } else { // 处理错误 } } catch (e: Exception) { // 处理网络异常 } }
如果你的请求格式是其他特殊类型(比如纯JSON里包含文件base64),只需要把文件转成base64字符串放到JSON字段里,不需要用@Multipart注解,直接用普通的@POST即可。
内容的提问来源于stack exchange,提问作者Pance S N
相关产品推荐
相关产品推荐

