gpt4 book ai didi

android - Android 上的 Kotlin 多部分请求

转载 作者:太空狗 更新时间:2023-10-29 13:02:48 30 4
gpt4 key购买 nike

对于我所面临的问题,如果能提供一些帮助,我将不胜感激。

我正在尝试将图像发布到 receipt parsing API并在构建实际请求时遇到问题。

我已经阅读并使用了 this article 中的大部分代码由 tarek 在 Medium 上编写,用于创建一个 MultiPart 类(使用 https),如下所示:

Multipart.kt

package com.example.skopal.foodme.services

import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.io.PrintWriter
import java.net.URL
import javax.net.ssl.HttpsURLConnection

class Multipart
/**
* This constructor initializes a new HTTPS POST request with content type
* is set to multipart/form-data
* @param url
* *
* @throws IOException
*/
@Throws(IOException::class)
constructor(url: URL) {

companion object {
private val LINE_FEED = "\r\n"
private val maxBufferSize = 1024 * 1024
private val charset = "UTF-8"
}

// creates a unique boundary based on time stamp
private val boundary: String = "===" + System.currentTimeMillis() + "==="
private val httpsConnection: HttpsURLConnection = url.openConnection() as HttpsURLConnection
private val outputStream: OutputStream
private val writer: PrintWriter

init {

httpsConnection.setRequestProperty("Accept-Charset", "UTF-8")
httpsConnection.setRequestProperty("Connection", "Keep-Alive")
httpsConnection.setRequestProperty("Cache-Control", "no-cache")
httpsConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary)
httpsConnection.setChunkedStreamingMode(maxBufferSize)
httpsConnection.doInput = true
httpsConnection.doOutput = true // indicates POST method
httpsConnection.useCaches = false
outputStream = httpsConnection.outputStream
writer = PrintWriter(OutputStreamWriter(outputStream, charset), true)
}

/**
* Adds a upload file section to the request
* @param fieldName - name attribute in <input type="file" name="..."></input>
* *
* @param uploadFile - a File to be uploaded
* *
* @throws IOException
*/
@Throws(IOException::class)
fun addFilePart(fieldName: String, uploadFile: File, fileName: String, fileType: String) {
writer.append("--").append(boundary).append(LINE_FEED)
writer.append("Content-Disposition: file; name=\"").append(fieldName)
.append("\"; filename=\"").append(fileName).append("\"").append(LINE_FEED)
writer.append("Content-Type: ").append(fileType).append(LINE_FEED)
writer.append(LINE_FEED)
writer.flush()

val inputStream = FileInputStream(uploadFile)
inputStream.copyTo(outputStream, maxBufferSize)

outputStream.flush()
inputStream.close()
writer.append(LINE_FEED)
writer.flush()
}

/**
* Adds a header field to the request.
* @param name - name of the header field
* *
* @param value - value of the header field
*/
fun addHeaderField(name: String, value: String) {
writer.append("$name: $value").append(LINE_FEED)
writer.flush()
}

/**
* Upload the file and receive a response from the server.
* @param onSuccess
* *
* @param onFailure
* *
* @throws IOException
*/
@Throws(IOException::class)
fun upload(onSuccess: (String) -> Unit, onFailure: ((Int) -> Unit)? = null) {
writer.append(LINE_FEED).flush()
writer.append("--").append(boundary).append("--")
.append(LINE_FEED)
writer.close()

try {
// checks server's status code first
val status = httpsConnection.responseCode
if (status == HttpsURLConnection.HTTP_OK) {
val reader = BufferedReader(InputStreamReader(httpsConnection.inputStream))
val response = reader.use(BufferedReader::readText)
httpsConnection.disconnect()
onSuccess(response)
} else {
onFailure?.invoke(status)
}

} catch (e: IOException) {
e.printStackTrace()
}

}

}

我正在调用上面的类:

ReceiptRecognitionApi.kt

fun parseReceipt(file: File, cb: (String) -> Unit) {
println("parseReceipt_1")

Thread {
val multipartReq = Multipart(URL(baseUrl))
multipartReq.addHeaderField("apikey", taggunApiKey)
multipartReq.addHeaderField("Accept", "application/json")

multipartReq.addFilePart("file", file, "receipt.jpg", "image/jpeg")

multipartReq.upload(
onSuccess = { response: String ->
cb(response)
},
onFailure = { responseCode: Int ->
cb("$responseCode")
})

}.start()
}

问题是在初始化 Multipart 对象后,我无法向其附加任何 header 或数据。例如。如果 parseReceipt 函数调用中的两个 addHeaderField 调用移动到 Multipart.ktinit block >, header 在请求中,否则不在。

我在这里做错了什么?

最佳答案

使用第三方库解决了我的问题:

Fuel.upload(path = baseUrl, method = Method.POST)
.header(TaggunConstants.taggunHeader(taggunApiKey))
.dataParts { _, _ -> listOf(DataPart(file, "file", "image/jpeg")) }
.responseJson { _, _, result ->
result.fold(
success = { data ->
cb(gson.fromJson(data.content, Receipt::class.java))
},
failure = { error ->
println("An error of type ${error.exception} happened: ${error.message}")
cb(null)
}
)
}

关于android - Android 上的 Kotlin 多部分请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53170549/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com