You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用Retrofit和RxJava发送含嵌套自定义类图片的请求

用Retrofit发送嵌套数据类中的图片到服务器

1. 调整数据类字段类型

先把LawyerModel中存储图片的字段类型从Any改为File(单张图片)和Array<File>(多张证书),确保能直接处理图片文件:

data class LawRegRequest(
    @SerializedName("email")
    var email: String,
    @SerializedName("first_name")
    var first_name: String,
    @SerializedName("last_name")
    var last_name: String,
    @SerializedName("phone")
    var phone: String,
    @SerializedName("password")
    var password: String,
    @SerializedName("password2")
    var password2: String,
    @SerializedName("lawyer")
    var lawyer: LawyerModel
)

data class LawyerModel(
    @SerializedName("father_name")
    var father_name: String,
    @SerializedName("gender")
    var gender: String,
    @SerializedName("birth_date")
    var birth_date: String,
    @SerializedName("university")
    var university: String,
    @SerializedName("service_languages")
    var service_languages: Array<Int>,
    @SerializedName("service_types")
    var service_types: Array<Int>,
    @SerializedName("voen")
    var voen: String,
    @SerializedName("law_practise")
    var law_practise: String,
    @SerializedName("lawyer_practise")
    var lawyer_practice: String,
    @SerializedName("lawyer_card")
    var lawyer_card: File, // 修改为File类型
    @SerializedName("certificates")
    var certificates: Array<File> // 修改为File数组
)

2. 定义Retrofit接口

因为要同时发送表单数据和文件,必须使用@Multipart注解构建请求,接口方法如下:

interface ApiService {
    @Multipart
    @POST("你的注册接口路径")
    suspend fun registerLawyer(
        @PartMap formData: Map<String, RequestBody>,
        @Part lawyerCard: MultipartBody.Part,
        @Part certificates: List<MultipartBody.Part>
    ): Response<你的响应数据类>
}

3. 构建请求体并发起请求

手动将嵌套数据类的字段映射为表单参数,同时将图片文件转换为MultipartBody.Part:

// 假设已创建LawRegRequest实例
val request = LawRegRequest(...)

// 构建表单数据Map,包含所有文本字段
val formData = mutableMapOf<String, RequestBody>()
// 添加顶级字段
formData["email"] = request.email.toRequestBody("text/plain".toMediaType())
formData["first_name"] = request.first_name.toRequestBody("text/plain".toMediaType())
formData["last_name"] = request.last_name.toRequestBody("text/plain".toMediaType())
formData["phone"] = request.phone.toRequestBody("text/plain".toMediaType())
formData["password"] = request.password.toRequestBody("text/plain".toMediaType())
formData["password2"] = request.password2.toRequestBody("text/plain".toMediaType())

// 添加LawyerModel的嵌套字段,格式为"lawyer[字段名]"
val lawyer = request.lawyer
formData["lawyer[father_name]"] = lawyer.father_name.toRequestBody("text/plain".toMediaType())
formData["lawyer[gender]"] = lawyer.gender.toRequestBody("text/plain".toMediaType())
formData["lawyer[birth_date]"] = lawyer.birth_date.toRequestBody("text/plain".toMediaType())
formData["lawyer[university]"] = lawyer.university.toRequestBody("text/plain".toMediaType())
formData["lawyer[voen]"] = lawyer.voen.toRequestBody("text/plain".toMediaType())
formData["lawyer[law_practise]"] = lawyer.law_practise.toRequestBody("text/plain".toMediaType())
formData["lawyer[lawyer_practise]"] = lawyer.lawyer_practice.toRequestBody("text/plain".toMediaType())

// 处理数组类型字段,格式为"lawyer[数组字段名][]"
lawyer.service_languages.forEach {
    formData["lawyer[service_languages][]"] = it.toString().toRequestBody("text/plain".toMediaType())
}
lawyer.service_types.forEach {
    formData["lawyer[service_types][]"] = it.toString().toRequestBody("text/plain".toMediaType())
}

// 处理律师证图片
val lawyerCardFile = lawyer.lawyer_card
val lawyerCardRequestBody = lawyerCardFile.asRequestBody("image/jpeg".toMediaType()) // 根据实际图片类型调整
val lawyerCardPart = MultipartBody.Part.createFormData(
    "lawyer[lawyer_card]",
    lawyerCardFile.name,
    lawyerCardRequestBody
)

// 处理证书图片数组
val certificateParts = mutableListOf<MultipartBody.Part>()
lawyer.certificates.forEach { file ->
    val certRequestBody = file.asRequestBody("image/jpeg".toMediaType())
    val part = MultipartBody.Part.createFormData(
        "lawyer[certificates][]",
        file.name,
        certRequestBody
    )
    certificateParts.add(part)
}

// 初始化Retrofit并发起请求
val apiService = Retrofit.Builder()
    .baseUrl("你的服务器基础地址")
    .addConverterFactory(GsonConverterFactory.create())
    .build()
    .create(ApiService::class.java)

val response = apiService.registerLawyer(formData, lawyerCardPart, certificateParts)

注意事项

  • 表单字段的命名格式(如lawyer[father_name])需要和后端服务器的参数解析规则一致,提前和后端开发确认。
  • 图片的MediaType要匹配实际文件类型,比如PNG用image/png,通用图片类型可以用image/*。
  • Android 13及以上版本需要申请READ_MEDIA_IMAGES权限来读取相册中的图片,低版本需要READ_EXTERNAL_STORAGE权限。

内容的提问来源于stack exchange,提问作者Sirac Seyidov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:30:59