如何在 Android 中使用 Retrofit2 发送 DTO 列表?

How to send DTO list using Retrofit2 in Android?

提问人:blonded 提问时间:10/31/2023 更新时间:10/31/2023 访问量:43

问:

我正在学习使用 Kotlin 的 Android 编程。我目前正在使用 Retrofit2 与服务器进行通信。需要传递到服务器端的数据之一是包含一组文本和一张图片的列表。当我发送它时,内容类型是“multipart/form-data”。

如果表示为数据类,则如下所示。

data class DataItem(
    val text: String,
    val image: File
)

我要发送的是此数据类对象的列表。 如果我把我想做的事情表达为改造服务定义的含义,它如下。

    @Multipart
    @POST("/post")
    fun addPost(
        @Part dataList: List<DataItem>   // But it didn't work
    ): Call<PostResponse>

我尝试以下方式更改数据类,但也没有成功。

data class DataItem(
    val text: RequestBody,
    val image: MultipartBody.Part
)

当服务器团队接收并使用此列表时,它必须能够按如下方式调用和使用:

dataList[0].text
dataList[0].image

我找到了这些方法。

  1. 仅发送一个非文件数据。
  2. 发送多个非文件数据。(零件地图)
  3. 仅发送一个文件数据。
  4. 发送多个文件数据。(列表<MultipartBody.Part>)

但是我找不到一种方法来发送包含非文件数据和文件数据的数据类对象列表。 如何定义改造服务,以按照我所说的方式发送服务器端可用的列表?

Android Kotlin 改造2

评论


答:

0赞 Guillaume Muret 10/31/2023 #1

要将列表作为 RequestBody 发送,必须先将其转换为 json 字符串,然后再将其包装到 RequestBody(使用扩展函数 toRequestBody())。

下面是一个示例:

@Multipart
@Headers("Accept: application/json")
@POST("/post")
fun addPost(
    @Part dataList: RequestBody,
    @Part file: MultipartBody.Part,
): Call<PostResponse>

还有邮政电话。我使用 Gson 将模型(列表)转换为 Json 字符串:

fun addPostCall(
    dataList: List<DataItem>,
    image: File,
) {
    myServiceClient.addPost(
        dataList = Gson()
            .toJson(dataList)
            .toRequestBody(),
        file = MultipartBody.Part.createFormData(
            "file",
            image.name,
            image.asRequestBody((image
                .toURI()
                .toURL()
                .openConnection().contentType ?: image.extension
                .takeIf { extension -> extension.isNotEmpty() }
                ?.let { extension ->
                    MimeTypeMap
                        .getSingleton()
                        .getMimeTypeFromExtension(extension)
                })?.toMediaTypeOrNull()
            ),
        )
    )
}

评论

0赞 blonded 11/1/2023
为什么文件与此代码分开发送?