我正在将我的HTTPrest客户端从ktor切换到apache httpclient 5.1.3。因此,我必须进行一些更改以使我的代码适应工作。MultipartEntity并不像预期的那样为我工作,因为当我从Base64字符串中放入字节数组时,显然某些字符存在一些解析问题,特别是“DEL”字符,它在ktor控制台输出中不可见,但在httpclient输出中显示为[0x7f]。
这是控制台日志行之间的比较,ktor在左边,httpclient在右边
所以,有效负载是不同的,我检查了是否有任何字符集不匹配,但这些似乎都不是问题。此外,我不知道ktor是一个kotlin库,而httpclient是一个java库是否有任何关系。
将第一行复制到vscode或其他编辑器中时,可以看到“5”字符之前有一个字符在这里不可见。在第二行中,所述字符显示为[0x7f]
[0xffffffc5] 5[0x1d]
我得到的响应是200 OK,但是响应体不是正确的。问题来自于试图在https://badgecheck.io验证包含嵌入数据的“烘焙图像”。如果我发送带有Postman图像的多部分请求,我会得到正确的数据,但是如果从我的应用程序通过httpclient发送,我会得到这个错误:
{"graph": [], "input":{"value": null},"报告":{"消息": [ { "名称":"DETECT_INPUT_TYPE","成功":false,"结果":"
这就是我构建多部分请求的方式:
inline fun <reified T> executeFormMultipartPost(
url: String,
bodyForm: ArrayList<NameValuePair>,
headers: Map<String, MutableList<String>> = mapOf()
): T {
val httpPost = HttpPost(url)
for (header in headers) {
header.value.forEach {
value -> httpPost.addHeader(header.key, value)
}
}
httpPost.addHeader("Accept-Charset", Charsets.UTF_8)
var nvParams: ArrayList<NameValuePair> = ArrayList<NameValuePair>()
for (n in bodyForm){
nvParams.add(n)
}
var builder: MultipartEntityBuilder = MultipartEntityBuilder.create().setContentType(ContentType.create(
"multipart/form-data"))
builder.setMode(HttpMultipartMode.EXTENDED)
builder.setMimeSubtype("form-data")
val contentDisposition = nvParams[0].value
val bytes = BaseEncoding.base64().decode(nvParams[1].value);
val image = ByteArrayBody(bytes, ContentType.create(
"multipart/form-data"),"badgeimage")
val data = StringBody(nvParams[2].value, ContentType.create(
"multipart/form-data"))
builder.addPart(nvParams[1].name, image)
builder.addPart(nvParams[2].name, data)
val httpEntity = builder.build()
httpPost.entity = httpEntity
val response = client.execute(httpPost)
return returnResponse(url, response)
}
那么,我能做些什么来解决这个问题呢?我错过了什么吗?
问题是“Content-Type”标头不安全,它被覆盖,从而破坏了请求。必须避免在请求对象中设置该标头,它工作正常。