我希望你能帮我解决问题。
我正在尝试将一张图片发布到收据解析API,但在构建实际请求时遇到了问题。
我已经阅读并使用了这篇文章中由tarek在Medium上编写的代码来创建一个类似以下的带有https的MultiPart类:
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 对象后,不能将任何标头或数据附加到它上面。例如,如果
parseReceipt
函数内的两个 addHeaderField
调用被移动到 Multipart.kt 中的 init
块中,则标头会在请求中出现,否则不会。
我在这里做错了什么?