【问题标题】:Retrofit2 failed to upload image with Multipart or RequestBodyRetrofit2 无法使用 Multipart 或 RequestBody 上传图像
【发布时间】:2020-12-05 01:59:05
【问题描述】:

我尝试了几种方法来为服务器发送图像,就像在 Postman 中一样

但实际上没有一个成功。

第一种方式通过@Multipart:

interface Api {   
@Multipart
@POST("/upload-file")
fun uploadFile(@Part("file") file: RequestBody,
               @Part("data") id: FileUploadModel): Single<Response<AdvertisementResponse>>
}

存储库类中的方法:

 override fun uploadFile(
    id: FileUploadModel,
    filePath: String
): Single<Response<AdvertisementResponse>> {

    val requestFile = RequestBody.create(MediaType.parse("image/*"), file)

    return api.uploadFile(requestFile, id)
}

RequestBody的第二种使用方式:

 @POST("/upload-file")
 fun uploadFile(@Body requestBody: RequestBody): Single<Response<AdvertisementResponse>>

存储库类中的方法:

override fun uploadFile(
    id: FileUploadModel,
    filePath: String
): Single<Response<AdvertisementResponse>> {

    val file = File(filePath)
    val builder = MultipartBody.Builder()
    builder.setType(MultipartBody.FORM)

    val requestFile = RequestBody.create(MediaType.parse("image/*"), file)

    builder.addFormDataPart("file", file.name, requestFile)
    builder.addFormDataPart("data", id.toJson())

    return api.uploadFile(builder.build())
}

第三种方式通过MultipartBody.Part:

@Multipart
@POST("/upload-file")
fun uploadFile(@Part("file") file: MultipartBody.Part,
               @Part("data") id: FileUploadModel): Single<Response<AdvertisementResponse>>

存储库类中的方法:

 override fun uploadFile(
    id: FileUploadModel,
    filePath: String
): Single<Response<AdvertisementResponse>> {

    val file = File(filePath)
    val requestFile = RequestBody.create(MediaType.parse("image/*"), file)
    val multipartFile = MultipartBody.Part.createFormData("file", file.name, requestFile)

    return api.uploadFile(multipartFile, id)
}

日志显示上传文件的 POST 请求未完成:

2020-08-15 13:52:35.828 D/OkHttpInterceptor: --> POST http://####/advertisement 2020-08-15 13:52:35.829 D/OkHttpInterceptor:内容类型:应用程序/json 2020-08-15 13:52:35.829 D/OkHttpInterceptor:内容长度:233 2020-08-15 13:52:35.829 D/OkHttpInterceptor: {"businessName":"mgskhsgmhz","email":"test@email.com","emirates":"Abu Dhabi","image":"/ storage/emulated/0/Pictures/1768cbfe-e5eb-4ae0-b642-be2733cfedbe969168674235591475.jpg","note":"","ownerName":"mhzm","phone":"1111","website":"" } 2020-08-15 13:52:35.829 D/OkHttpInterceptor: --> END POST (233-byte body) 2020-08-15 13:52:36.233 D/OkHttpInterceptor: POST http://####/upload-file 2020-08-15 13:52:36.278 D/OkHttpInterceptor: Content-Type: multipart/form-data;边界=894cbe1b-0fc4-47c6-849d-3764193c214f 2020-08-15 13:52:36.279 D/OkHttpInterceptor:内容长度:104305

我想知道为什么 Retrofit 不能完成这样的请求。

感谢您的任何建议

干杯

【问题讨论】:

    标签: android postman retrofit retrofit2 multipartform-data


    【解决方案1】:

    问题是由于无法从磁盘读取文件造成的。

    在 Android 清单中添加 android:requestLegacyExternalStorage="true" 对我来说适用于 Android sdk 29。

    <application
    android:name=".MyApplication"
    android:requestLegacyExternalStorage="true" ...
    

    除了添加&lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;权限。

    【讨论】:

    • 它只能在 android 10 上运行,但不能在它上面运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多