Android Загрузить файл через OKHTTP, не используя MultiPart - PullRequest
0 голосов
/ 22 января 2020

Это код, который я должен загрузить файл:

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. Поэтому мне нужно отправить файл в один go. Как это возможно?

Я также пытался с 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

Что я пропускаю / ошибаюсь здесь

Ответы [ 2 ]

0 голосов
/ 22 января 2020

После нескольких попыток использование этого в моем 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 ""
0 голосов
/ 22 января 2020

Я думаю, что это примерно getBytes()

Будьте осторожны при его использовании, потому что вы должны передать параметр кодировки символов, например .getBytes("UTF-8")

Если вы не передадите какой-либо параметр будет использоваться системное значение по умолчанию.

Пожалуйста, сделайте следующее:

fileOutput.write (" ВАША ДЕКОДИРОВАННАЯ СТРОКА ". getBytes ("UTF-8"));

...