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

如何在Retrofit中发送含多类型参数及图片的Multipart请求?

Retrofit Multipart Form Request with Mixed Data Types & File Attachment: Fixes & Best Practices

Let's walk through your implementation and fix the key issues that might be causing problems with your multipart request:

1. Core Issues in Current Code

  • Raw Int/Boolean @Part Parameters: Retrofit doesn’t handle raw primitive types (like Int, Boolean) directly in @Multipart requests. These need to be wrapped into RequestBody to ensure proper form-data serialization.
  • Incorrect MediaType for String Fields: Using multipart/form-data for regular string fields is unnecessary; text/plain is the appropriate media type for simple text values.
  • Potential File Path Mistake: When creating the image part, make sure imageFilePath is a File instance (not just a string path) – your code references store.imagePathFile?.name, so double-check the file object is valid.

2. Corrected Retrofit Interface

@Multipart
@POST(AppConstants.Network.CREATE_STORE)
fun createStore(
    @Header("Authorization") token: String,
    // Image part (nullable if optional)
    @Part imagePath: MultipartBody.Part?,
    // String fields wrapped in RequestBody
    @Part("Name") storeName: RequestBody,
    @Part("StoreOwnerName") storeOwnerName: RequestBody,
    @Part("StoreOwnerGender") storeOwnerGender: RequestBody,
    @Part("StoreOwnerDob") storeOwnerDob: RequestBody,
    @Part("AddressLine1") addressLine1: RequestBody,
    @Part("AddressLine2") addressLine2: RequestBody,
    @Part("AddressLine3") addressLine3: RequestBody,
    @Part("Place") place: RequestBody,
    @Part("PinCode") pinCode: RequestBody, // Changed from Int to RequestBody
    @Part("ContactNumber") contactNumber: RequestBody,
    @Part("Email") email: RequestBody,
    // Boolean fields wrapped in RequestBody
    @Part("IsRegistered") isRegistered: RequestBody, // Changed from Boolean to RequestBody
    @Part("HasGst") hasGst: RequestBody, // Changed from Boolean to RequestBody
    @Part("GSTNumber") GSTNumber: RequestBody, // Changed from Int to RequestBody
    @Part("HasInsurance") hasInsurance: RequestBody, // Changed from Boolean to RequestBody
    @Part("HasBankAccount") hasBankAccount: RequestBody, // Changed from Boolean to RequestBody
    // Int fields wrapped in RequestBody
    @Part("StaffSize") staffSize: RequestBody, // Changed from Int to RequestBody
    @Part("StoreSize") storeSize: RequestBody, // Changed from Int to RequestBody
    @Part("RunningFrom") runningFromDate: RequestBody,
    @Part("StoreTypeId") storeTypeId: RequestBody, // Changed from Int to RequestBody
    @Part("AverageTurnOver") averageTurnOver: RequestBody, // Changed from Int to RequestBody
    @Part("OwnerResponseId") ownerResponseId: RequestBody, // Changed from Int to RequestBody
    @Part("Remarks") remarks: RequestBody
): Single<ResponseBody>

3. Corrected API Call Implementation

// Helper functions to reduce code duplication
fun createTextRequestBody(value: String): RequestBody {
    return RequestBody.create(MediaType.parse("text/plain"), value)
}

fun createPrimitiveRequestBody(value: Any): RequestBody {
    return RequestBody.create(MediaType.parse("text/plain"), value.toString())
}

// Usage in your call
apiService.createStore(
    token = "bearer ${AppPreferences(context!!).token!!}",
    imagePath = store.imagePathFile?.let { imageFile ->
        MultipartBody.Part.createFormData(
            name = "ImagePath",
            filename = imageFile.name,
            body = RequestBody.create(MediaType.parse("image/*"), imageFile)
        )
    }, // Safely handle nullable file
    storeName = createTextRequestBody("Your Name"),
    storeOwnerName = createTextRequestBody("Your Name"),
    storeOwnerGender = createTextRequestBody("Your Name"),
    storeOwnerDob = createTextRequestBody("Your Name"),
    addressLine1 = createTextRequestBody("Your Name"),
    addressLine2 = createTextRequestBody("Your Name"),
    addressLine3 = createTextRequestBody("Your Name"),
    place = createTextRequestBody("Fsafa"),
    pinCode = createPrimitiveRequestBody(642526),
    contactNumber = createTextRequestBody("Your Name"),
    email = createTextRequestBody("etet@gga.co"),
    isRegistered = createPrimitiveRequestBody(false),
    hasGst = createPrimitiveRequestBody(true),
    GSTNumber = createPrimitiveRequestBody(23423432),
    hasBankAccount = createPrimitiveRequestBody(false),
    averageTurnOver = createPrimitiveRequestBody(345346),
    hasInsurance = createPrimitiveRequestBody(false),
    staffSize = createPrimitiveRequestBody(546),
    ownerResponseId = createPrimitiveRequestBody(2),
    remarks = createTextRequestBody("Your Name"),
    runningFromDate = createTextRequestBody("Your Name"),
    storeSize = createPrimitiveRequestBody(324),
    storeTypeId = createPrimitiveRequestBody(2)
)

4. Key Explanations

  • Primitive Type Wrapping: Converting Int/Boolean to strings and wrapping in RequestBody ensures Retrofit sends these values as valid form-data fields, avoiding unsupported raw serialization.
  • Safe Image Handling: Using let creates the image part only if the file exists, preventing null pointer exceptions. Passing the actual File object (not a string path) is critical for successful file upload.
  • MediaType Choice: text/plain is the standard for simple text/primitive values in form-data; multipart/form-data refers to the overall request structure, not individual fields.
  • Cleaner Code: Helper functions eliminate repetitive RequestBody.create calls and make the implementation easier to maintain.

5. Additional Checks

  • Confirm your server endpoint expects exact, case-sensitive field names (e.g., "ImagePath", "Name") as specified in @Part.
  • Verify the Authorization header format (your "bearer " + token is standard, but double-check the token value is valid).
  • If image upload is optional, keep imagePath nullable and pass null when no image is provided.

内容的提问来源于stack exchange,提问作者Manoj Perumarath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:26:02