有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在CRONET中发送json对象作为post请求?

我正在开发一个安卓应用程序,在这个应用程序中,我使用cronet向服务器发送数据。现在我想用json对象向服务器发送数据,但不知道如何发送对象

下面是我的GET方法(工作)的代码片段

有人可以分享如何在安卓 cronet中使用POST方法吗

依赖关系

 implementation 'org.chromium.net:cronet-embedded:71.3578.98'

主要活动

import 安卓.os.Bundle
import 安卓x.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 安卓.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
    }

共 (1) 个答案

  1. # 1 楼答案

    示例:

        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类:

    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)
        }
    
    }