【问题标题】:Android Upload a file via OKHTTP not using MultiPartAndroid通过OKHTTP上传文件不使用MultiPart
【发布时间】:2020-05-08 11:35:39
【问题描述】:

这是我必须上传文件的代码:

fun uploadFile(oid: String, file: Attachment, mime: String, callback: Callback): Call {
    val url = getURL(XelionOKHttpAPIRestLinks.UPLOAD_FILE.replace("__OID__", oid))
    var mediaType = mime.toMediaType()
    var body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", file.originalLocation,
            RequestBody.create(mediaType, file.originalLocation)).build()
    val request = Request.Builder().url(url).headers(setHeaderUpload(mime, file.commonName, file.size.toString())).post(body).build()
    val call = client.newCall(request)
    call.enqueue(callback)
    return call
}

这对我来说非常有效。但是服务器不支持 MultiPart。所以我需要一次性发送文件。这怎么可能?

我也尝试过使用 HTTPConnection:

     var async = object : AsyncTask<Void, Void, String>() {
        override fun doInBackground(vararg params: Void?): String {
            val url = URL(getURL(XelionOKHttpAPIRestLinks.UPLOAD_FILE.replace("__OID__", oid)))
            try {
                val urlConnection: HttpURLConnection = url.openConnection() as HttpURLConnection
                var nameOnly = attachment.commonName.split("/")
                urlConnection.setRequestMethod("POST")
                urlConnection.setDoOutput(true)
                urlConnection.setRequestProperty("Authorization", "xelion " + XelionPreferences.INSTANCE.authToken)
                urlConnection.setRequestProperty("Content-Type", mime)
                urlConnection.setRequestProperty("Content-Disposition", "attachment; filename=\"" + nameOnly.last() + "\"")
                urlConnection.setRequestProperty("Content-Length", attachment.size.toString())
                urlConnection.connect()
                val fileOutput = FileOutputStream(file)
                var decodedBytes = Base64.decode(attachment.contentsB64String, Base64.NO_WRAP)
                fileOutput.write(decodedBytes)
                fileOutput.close()
                var responseCode = urlConnection.getResponseCode()
                callback.sendData("")
            } catch (e: MalformedURLException) {
                e.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return ""
        }
    }
    async.execute()
}

但是为此我遇到了这个问题:

java.net.ProtocolException: content-length promised 318848 bytes, but received 0

我在这里遗漏了什么/弄错了什么?

【问题讨论】:

    标签: android networking file-upload upload okhttp


    【解决方案1】:

    多次尝试后,在我的 AsyncTask 中使用它使其工作:

    val url = URL(getURL(XelionOKHttpAPIRestLinks.UPLOAD_FILE.replace("__OID__", oid)))
                var baos = ByteArrayOutputStream()
                try {
                    val urlConnection: HttpURLConnection = url.openConnection() as HttpURLConnection
                    var nameOnly = attachment.commonName.split("/")
                    urlConnection.setRequestMethod("POST")
                    urlConnection.setDoInput(true)
                    urlConnection.setDoOutput(true)
                    urlConnection.setRequestProperty("Authorization", "xelion " + XelionPreferences.INSTANCE.authToken)
                    urlConnection.setRequestProperty("Content-Type", mime)
                    urlConnection.setRequestProperty("Content-Disposition", "attachment; filename=\"" + nameOnly.last() + "\"")
                    urlConnection.connect()
                    var decodedBytes = Base64.decode(attachment.contentsB64String, Base64.DEFAULT)
                    urlConnection.getOutputStream().write(decodedBytes)
    
                    val `is`: InputStream = urlConnection.getInputStream()
                    val b = ByteArray(1024)
    
                    while (`is`.read(b) !== -1) baos.write(b)
    
                    urlConnection.disconnect()
                    callback.sendData("")
                } catch (e: MalformedURLException) {
                    e.printStackTrace()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                return ""
    

    【讨论】:

      【解决方案2】:

      我认为是关于getBytes()

      使用时要小心,因为你必须传递字符编码参数,如.getBytes("UTF-8")

      如果不传递任何参数,它将使用系统默认值。

      请喜欢:

      fileOutput.write("你的解码字符串".getBytes("UTF-8"));

      【讨论】:

      • 在哪里?我尝试了attachment.contentsB64String.getBytes("UTF-8"),但字符串的 getBytes 是“未解决的引用”。如果我在“decodedBytes”(这是一个 byte[] )上尝试它也是一样的
      • 我使用了:" var decodedBytes = attachment.contentsB64String.toByteArray(Charsets.UTF_8)" 但在 urlConnection.getResponseCode 上我仍然得到相同的 PROTOCOL EXCEPTION ERROR
      猜你喜欢
      • 2020-12-31
      • 2016-12-14
      • 2021-01-19
      • 1970-01-01
      • 2015-08-01
      • 2019-08-27
      • 2018-03-28
      • 2021-02-21
      • 1970-01-01
      相关资源
      最近更新 更多