如何在 CRONET 中将 json 对象作为 post 请求发送?
How to send json object as post request in CRONET?
我正在开发 android 应用程序,我在其中使用 cronet 将数据发送到服务器现在我想将数据发送到 json 对象中的服务器但不知道如何发送对象?
以下是我的 GET 方法代码片段(工作中)。
任何人都可以分享如何在 android cronet 中使用 POST 方法吗?
依赖关系
implementation 'org.chromium.net:cronet-embedded:71.3578.98'
主要活动
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
companion object {
// Web page url
private const val JSON_PLACEHOLDER_API_URL = "https://jsonplaceholder.typicode.com/todos/1"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Build a Cronet engine
val cronetEngine =
CronetEngine.Builder(this)
.enableBrotli(true)
.build()
// Build the request
val request =
cronetEngine.newUrlRequestBuilder(
JSON_PLACEHOLDER_API_URL,
RequestCallback(),
Executors.newSingleThreadExecutor()
).build()
// Start the request
request.start()
}
}
请求回调
import android.util.Log
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.nio.ByteBuffer
import java.nio.charset.Charset
/**
* Different methods are invoked for different response status
*/
class RequestCallback : UrlRequest.Callback() {
companion object {
// Log cat tag
private val TAG = RequestCallback::class.java.simpleName
}
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Started")
val statusCode = info?.httpStatusCode
Log.i(TAG, "Status Code $statusCode")
if (statusCode == 200) {
// Read the buffer
request?.read(ByteBuffer.allocateDirect(32 * 1024))
}
}
override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
Log.i(TAG, "Response Completed")
// Flip the buffer
byteBuffer?.flip()
// Convert the byte buffer to a string
byteBuffer?.let {
val byteArray = ByteArray(it.remaining())
it.get(byteArray)
String(byteArray, Charset.forName("UTF-8"))
}.apply {
Log.d(TAG, "Response: $this")
}
// Clear the buffer
byteBuffer?.clear()
// Read the buffer
request?.read(byteBuffer)
}
override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
Log.e(TAG, "Response Failed: ${error?.message}")
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Succeeded")
}
override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
Log.i(TAG, "Response Redirect to $newLocationUrl")
request?.followRedirect()
}
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
Log.i(TAG, "Response cancelled")
}
}
输出
Response: {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
示例:
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)
}
}
我正在开发 android 应用程序,我在其中使用 cronet 将数据发送到服务器现在我想将数据发送到 json 对象中的服务器但不知道如何发送对象?
以下是我的 GET 方法代码片段(工作中)。
任何人都可以分享如何在 android cronet 中使用 POST 方法吗?
依赖关系
implementation 'org.chromium.net:cronet-embedded:71.3578.98'
主要活动
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
companion object {
// Web page url
private const val JSON_PLACEHOLDER_API_URL = "https://jsonplaceholder.typicode.com/todos/1"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Build a Cronet engine
val cronetEngine =
CronetEngine.Builder(this)
.enableBrotli(true)
.build()
// Build the request
val request =
cronetEngine.newUrlRequestBuilder(
JSON_PLACEHOLDER_API_URL,
RequestCallback(),
Executors.newSingleThreadExecutor()
).build()
// Start the request
request.start()
}
}
请求回调
import android.util.Log
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.nio.ByteBuffer
import java.nio.charset.Charset
/**
* Different methods are invoked for different response status
*/
class RequestCallback : UrlRequest.Callback() {
companion object {
// Log cat tag
private val TAG = RequestCallback::class.java.simpleName
}
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Started")
val statusCode = info?.httpStatusCode
Log.i(TAG, "Status Code $statusCode")
if (statusCode == 200) {
// Read the buffer
request?.read(ByteBuffer.allocateDirect(32 * 1024))
}
}
override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
Log.i(TAG, "Response Completed")
// Flip the buffer
byteBuffer?.flip()
// Convert the byte buffer to a string
byteBuffer?.let {
val byteArray = ByteArray(it.remaining())
it.get(byteArray)
String(byteArray, Charset.forName("UTF-8"))
}.apply {
Log.d(TAG, "Response: $this")
}
// Clear the buffer
byteBuffer?.clear()
// Read the buffer
request?.read(byteBuffer)
}
override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
Log.e(TAG, "Response Failed: ${error?.message}")
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Succeeded")
}
override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
Log.i(TAG, "Response Redirect to $newLocationUrl")
request?.followRedirect()
}
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
Log.i(TAG, "Response cancelled")
}
}
输出
Response: {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
示例:
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)
}
}