Last active
August 20, 2021 14:33
-
-
Save ycui1/5d25672430e6c014a9ef6b422f82652e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.t2r2.volleyexample | |
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 = "imageRequest${System.currentTimeMillis()}" | |
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()) { | |
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 { | |
Response.success(response, HttpHeaderParser.parseCacheHeaders(response)) | |
} catch (e: Exception) { | |
Response.error(ParseError(e)) | |
} | |
} | |
override fun deliverResponse(response: NetworkResponse) { | |
responseListener?.onResponse(response) | |
} | |
override fun deliverError(error: VolleyError) { | |
errorListener?.onErrorResponse(error) | |
} | |
@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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment