Android通过OKHTTP上传文件不使用MultiPart
Posted
技术标签:
【中文标题】Android通过OKHTTP上传文件不使用MultiPart【英文标题】:Android Upload a file via OKHTTP not using 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
我在这里遗漏了什么/弄错了什么?
【问题讨论】:
【参考方案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以上是关于Android通过OKHTTP上传文件不使用MultiPart的主要内容,如果未能解决你的问题,请参考以下文章
Android必知必会-使用okhttp的PUT方式上传文件
Okhttp 使用(同步、异步/get、post/上传文件)