【问题标题】:Getting 500 error in multipart request in android volley在 android volley 中的多部分请求中出现 500 错误
【发布时间】:2021-01-28 07:15:27
【问题描述】:

我想上传图片和一些数据到服务器。我正在为此使用凌空多部分请求。上传图片时出现 500 错误。我认为它与标题部分有关。 API 在 POSTMAN 中运行良好

如果我请求没有边界值,我会收到 400 错误。请提供任何解决方案。提前致谢


private fun uploadImage() {
        OFC_Utils.showProgressDialog(this, "", "")
        val token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwMGE1NzQxNC00M2JmLTQwYTEtODEyMS0zNWIzMTYyMGViZGIiLCJkZXZpY2VJZCI6IjVhNjYyMWQ5LTQwZTgtNGJlMC05MjQ4LWIzY2I2MDkzODdhZSIsImZhcm1JZCI6IiIsImxhbmd1YWdlIjoiRW5nbGlzaCIsInRpbWVab25lIjoiSW5kaWEgU3RhbmRhcmQgVGltZSIsInJvbGUiOiJQQVJBVkVURVJJTkFSSUFOIiwidmVyaWZpY2F0aW9uU3RhdHVzIjoiRmFsc2UiLCJuYmYiOjE2MTE4MTcxNzMsImV4cCI6MTYxMTgxODk3MywiaWF0IjoxNjExODE3MTczfQ.Eo8C6BRyY116JPJmVHEYMPcoZ1Rk2N_mEw4Hj-g4z8M"
        val BOUNDARY = "--XX--" //This the boundary which is used by the server to split the post parameters.
        val MULTIPART_FORMDATA = "multipart/form-data;boundary=$BOUNDARY"
        imageData ?: return
        val request = object : VolleyFileUploadRequest(
                Method.POST,
                Constants.Service_Urls.UPLOAD_FARM_DETAILS,
                Response.Listener {
                    OFC_Utils.hideProgressDialog()
                    println("response is: $it")
                },
                Response.ErrorListener { error ->
                    var response = ""

                    OFC_Utils.hideProgressDialog()
                    val networkResponse = error.networkResponse
                    if (networkResponse != null && networkResponse.data != null) {
//                        val jsonError = String(networkResponse.data)
//                        val jsonobject:JSONObject= JSONObject(String(networkResponse.data))
                        Log.d("jsonerror", String(networkResponse.data))
                        // response=jsonobject.optString("status")
                    }
                }

        ) {
            override fun getByteData(): Map<String, Any>? {
                val params = HashMap<String, FileDataPart>()
                val imagename = System.currentTimeMillis()
                params["ProfilePicFile"] = FileDataPart(imagename.toString(), imageData!!, "png")
                return params
            }

            override fun getBodyContentType(): String {
                return MULTIPART_FORMDATA
            }


            override fun getBody(): ByteArray {
                val params = HashMap<String, String>()
                params.put("CountryCode", "+91")
                params.put("Phone", "1234567890")
                params.put("Role", "PARAVET")
                params.put("Name", "NAGS")
                params.put("PreferredLanguage", "ENGLISH")
                params.put("DeviceName", "REDMI6A")
                params.put("DeviceType", "MOBILE")
                params.put("Location", "banglore")
                Log.d("params1", params.toString())
                return params.toString().toByteArray()
            }


            override fun getHeaders(): MutableMap<String, String> {
                val boundary = "apiclient-" + System.currentTimeMillis()
                val headers = java.util.HashMap<String, String>()
                Log.d("boundary", boundary.toString())
                headers["Authorization"] = "bearer $token"
                headers["Content-Type"] = MULTIPART_FORMDATA



                return headers

            }


        }
        Volley.newRequestQueue(this).add(request)
    }






import android.util.Log
import com.android.volley.*
import com.android.volley.toolbox.HttpHeaderParser
import java.io.*
import kotlin.math.min


open class VolleyFileUploadRequest(
        method: Int,
        url: String,
        listener: Response.Listener<NetworkResponse>,
        errorListener: Response.ErrorListener) : Request<NetworkResponse>(method, url, errorListener) {
    private var responseListener: Response.Listener<NetworkResponse>? = null
    init {
        this.responseListener = listener
    }

    private var headers: Map<String, String>? = null
    private val divider: String = "--"
    private val ending = "\r\n"
    //private val boundary = "apiclient-" + System.currentTimeMillis()
    private val boundary = "--XX--"


    override fun getHeaders(): MutableMap<String, String> =
            when(headers) {
                null -> super.getHeaders()
                else -> headers!!.toMutableMap()
            }

    override fun getBodyContentType() = "multipart/form-data; boundary=" + boundary


    @Throws(AuthFailureError::class)
    override fun getBody(): ByteArray {
        val byteArrayOutputStream = ByteArrayOutputStream()
        val dataOutputStream = DataOutputStream(byteArrayOutputStream)
        try {
            if (params != null && params.isNotEmpty()) {
                Log.d("params",params.toString())
                processParams(dataOutputStream, params, paramsEncoding)
            }
            val data = getByteData() as? Map<String, FileDataPart>?
            if (data != null && data.isNotEmpty()) {
                processData(dataOutputStream, data)
            }
            dataOutputStream.writeBytes(divider + boundary + divider + ending)
            return byteArrayOutputStream.toByteArray()

        } catch (e: IOException) {
            e.printStackTrace()
        }
        return super.getBody()
    }

    @Throws(AuthFailureError::class)
    open fun getByteData(): Map<String, Any>? {
        return null
    }

    override fun parseNetworkResponse(response: NetworkResponse): Response<NetworkResponse> {
        return try {
            Log.d("del_params",response.toString())
            Response.success(response, HttpHeaderParser.parseCacheHeaders(response))

        } catch (e: Exception) {
            Response.error(ParseError(e))
        }
    }

    override fun deliverResponse(response: NetworkResponse) {
        responseListener?.onResponse(response)
        Log.d("del_params",response.data.toString())
    }

    override fun deliverError(error: VolleyError) {
        errorListener?.onErrorResponse(error)
//        Log.d("error_params",error.message)
    }

    @Throws(IOException::class)
    private fun processParams(dataOutputStream: DataOutputStream, params: Map<String, String>, encoding: String) {
        try {
            params.forEach {
                dataOutputStream.writeBytes(divider + boundary + ending)
                dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"${it.key}\"$ending")
                dataOutputStream.writeBytes(ending)
                dataOutputStream.writeBytes(it.value + ending)
            }
        } catch (e: UnsupportedEncodingException) {
            throw RuntimeException("Unsupported encoding not supported: $encoding with error: ${e.message}", e)
        }
    }

    @Throws(IOException::class)
    private fun processData(dataOutputStream: DataOutputStream, data: Map<String, FileDataPart>) {
        data.forEach {
            val dataFile = it.value
            dataOutputStream.writeBytes("$divider$boundary$ending")
            dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"${it.key}\"; filename=\"${dataFile.fileName}\"$ending")
            if (dataFile.type != null && dataFile.type.trim().isNotEmpty()) {
                dataOutputStream.writeBytes("Content-Type: ${dataFile.type}$ending")
            }
            dataOutputStream.writeBytes(ending)
            val fileInputStream = ByteArrayInputStream(dataFile.data)
            var bytesAvailable = fileInputStream.available()
            val maxBufferSize = 1024 * 1024
            var bufferSize = min(bytesAvailable, maxBufferSize)
            val buffer = ByteArray(bufferSize)
            var bytesRead = fileInputStream.read(buffer, 0, bufferSize)
            while (bytesRead > 0) {
                dataOutputStream.write(buffer, 0, bufferSize)
                bytesAvailable = fileInputStream.available()
                bufferSize = min(bytesAvailable, maxBufferSize)
                bytesRead = fileInputStream.read(buffer, 0, bufferSize)
            }
            dataOutputStream.writeBytes(ending)
        }
    }
}

class FileDataPart(var fileName: String?, var data: ByteArray, var type: String)

【问题讨论】:

  • 500 错误代码是指服务器端错误。 400错误码属于客户端。
  • 但 API 在邮递员中工作正常

标签: android kotlin android-volley


【解决方案1】:

500 表示服务器错误。如果它在 Postman 上运行良好但在您的应用程序上运行良好,则意味着您没有在应用程序中正确发送请求,但您在 Postman 中发送请求。这可能是因为您尝试发送的数据或任何其他原因。尝试发送您通过 Postman 发送的相同数据或使用相同的标头等。

但由于 500 表示服务器错误,您可以让后端开发人员告诉您确切的错误是什么,以便您轻松修复它。

【讨论】:

  • 在邮递员中我只传递令牌。数据相同
猜你喜欢
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 2017-04-15
相关资源
最近更新 更多