如何使用 CRONET 在 Android 中发送“multipart/form-data”POST?
How to send a “multipart/form-data” POST in Android with CRONET?
有没有人能够使用 CRONET 在 Android 中发送 multipart/form-data POST?我没有成功尝试使用 POST 请求将 image/png 上传到我们的服务器,我很好奇是否有人上传过。
注意:我只需要基于 CRONET 的解决方案
Post 方法示例:
val myBuilder = CronetEngine.Builder(context)
// Enable caching of HTTP data and
// other information like QUIC server information, HTTP/2 protocol and QUIC protocol.
val cronetEngine: CronetEngine = myBuilder
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
.enableHttp2(true)
.enableQuic(true)
.build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
"FULL-URL",
MyUrlRequestCallback(),
executor
)
// Content-Type is required, removing it will cause Exception
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = MyUploadDataProvider()
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()
MyUploadDataProvider Class:
import android.util.Log
import org.chromium.net.UploadDataProvider
import org.chromium.net.UploadDataSink
import java.lang.Exception
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
private const val TAG = "MyUploadDataProvider"
//TODO replace username and passowrd "_user & _pass"
var string: String ="{\"username\":\"_user\",\"password\":\"_pass\"}"
val charset = StandardCharsets.UTF_8
class MyUploadDataProvider() : UploadDataProvider() {
override fun getLength(): Long {
val size:Long = string.length.toLong()
Log.e(TAG,"Length = "+size)
return size
}
override fun rewind(uploadDataSink: UploadDataSink?) {
Log.e(TAG,"REWIND IS CALLED")
uploadDataSink!!.onRewindSucceeded()
}
override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
Log.e(TAG,"READ IS CALLED")
byteBuffer!!.put(string.toByteArray(charset))
//byteBuffer.rewind()
//For chunked uploads, true if this is the final read. It must be false for non-chunked uploads.
uploadDataSink!!.onReadSucceeded(false)
}
}
要上传文件,我宁愿使用 UploadDataProviders
中的 create()
方法。借助这些方法,您可以创建一个 UploadDataProvider
来上传 File
、FileDescriptor
甚至 byte
数组。例如,要上传一个空的字节数组,我可以这样做:
...
val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
...
或者,如果我有一个File
对象,我也可以直接将它传递给create方法:
...
val myUploadDataProvider = UploadDataProviders.create(someFile)
...
因此,整个代码如下所示:
...
val myBuilder = CronetEngine.Builder(this)
val cronetEngine: CronetEngine = myBuilder
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
.enableHttp2(true)
.enableQuic(true)
.build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
"http://ptsv2.com/",
object : UrlRequest.Callback() {
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
}
override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
}
override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
}
override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
}
},
executor
)
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()
...
是的,cronet 和 volley 是 google 官方支持的库,但也请考虑 google 的另一面...google 也官方支持改造...因为它的速度很快和更少的样板代码...请阅读一些博客,您也可以访问 udacity 纳米学位课程,其中说改造最适合网络...
有没有人能够使用 CRONET 在 Android 中发送 multipart/form-data POST?我没有成功尝试使用 POST 请求将 image/png 上传到我们的服务器,我很好奇是否有人上传过。
注意:我只需要基于 CRONET 的解决方案
Post 方法示例:
val myBuilder = CronetEngine.Builder(context)
// Enable caching of HTTP data and
// other information like QUIC server information, HTTP/2 protocol and QUIC protocol.
val cronetEngine: CronetEngine = myBuilder
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
.enableHttp2(true)
.enableQuic(true)
.build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
"FULL-URL",
MyUrlRequestCallback(),
executor
)
// Content-Type is required, removing it will cause Exception
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = MyUploadDataProvider()
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()
MyUploadDataProvider Class:
import android.util.Log
import org.chromium.net.UploadDataProvider
import org.chromium.net.UploadDataSink
import java.lang.Exception
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
private const val TAG = "MyUploadDataProvider"
//TODO replace username and passowrd "_user & _pass"
var string: String ="{\"username\":\"_user\",\"password\":\"_pass\"}"
val charset = StandardCharsets.UTF_8
class MyUploadDataProvider() : UploadDataProvider() {
override fun getLength(): Long {
val size:Long = string.length.toLong()
Log.e(TAG,"Length = "+size)
return size
}
override fun rewind(uploadDataSink: UploadDataSink?) {
Log.e(TAG,"REWIND IS CALLED")
uploadDataSink!!.onRewindSucceeded()
}
override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
Log.e(TAG,"READ IS CALLED")
byteBuffer!!.put(string.toByteArray(charset))
//byteBuffer.rewind()
//For chunked uploads, true if this is the final read. It must be false for non-chunked uploads.
uploadDataSink!!.onReadSucceeded(false)
}
}
要上传文件,我宁愿使用 UploadDataProviders
中的 create()
方法。借助这些方法,您可以创建一个 UploadDataProvider
来上传 File
、FileDescriptor
甚至 byte
数组。例如,要上传一个空的字节数组,我可以这样做:
...
val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
...
或者,如果我有一个File
对象,我也可以直接将它传递给create方法:
...
val myUploadDataProvider = UploadDataProviders.create(someFile)
...
因此,整个代码如下所示:
...
val myBuilder = CronetEngine.Builder(this)
val cronetEngine: CronetEngine = myBuilder
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
.enableHttp2(true)
.enableQuic(true)
.build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
"http://ptsv2.com/",
object : UrlRequest.Callback() {
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
}
override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
}
override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
}
override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
}
},
executor
)
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()
...
是的,cronet 和 volley 是 google 官方支持的库,但也请考虑 google 的另一面...google 也官方支持改造...因为它的速度很快和更少的样板代码...请阅读一些博客,您也可以访问 udacity 纳米学位课程,其中说改造最适合网络...