Java 的 HttpURLConnection 似乎在请求中附加了 0018 字符?

Java's HttpURLConnection seems to append 0018 character in request?

我正在尝试通过 HTTP 发送图像。

我已经通过 Chrome 对其进行了测试,使用 Wireshark 查看请求的详细信息。 headers 和多部分内容之间的间隔是 \r\n.

然而,我在 Java 中的实现似乎将 \r\n 和字符 0018 分开,根据 FileFormat.infoCANCEL 字符.

我正在使用 Java's HttpURLConnection(从 Kotlin 访问,但这不应该是问题所在),这是用于写入文件内容的代码示例:

val endl = "\r\n"
val hyphens = "--"
val boundary = "----${System.currentTimeMillis()}---"

// conn is an HttpURLConnection
val output = conn.outputStream
val writer = DataOutputStream(output)
writer.flush()

writer.writeUTF(hyphens + boundary + endl) // first time writing
writer.writeUTF("Content-Disposition: form-data; name: [REDACTED]" + endl)
writer.writeUTF("Content-Type: [REDACTED]" + endl)
writer.writeUTF(endl)

// [REDACTED: Writing the contents of the file]

writer.writeUTF(endl)
writer.writeUTF(hyphens + boundary + hyphens + endl)

writer.flush()
writer.close()

(可以找到此示例的完整代码 here,第 99-144 行)

字符 0018 被插入到该代码示例之前,并且紧接在 headers 之后(它们是使用 HttpURLConnection.setRequestProperty 编写的,所以我不认为它们可能是问题所在...以防万一,您可以找到代码 here,第 64-91 行)。

这里是请求的开头 body:

------1544883782650---
DContent-Disposition: form-data; name: "avatar"; filename: "wf.png"
Content-Type: image/png

(您可以在第一行的开头看到 CANCEL 字符,就在边界之前)。

与Chrome提出的要求相比:

------WebKitFormBoundaryAhYDuYuz5IuXB95v
Content-Disposition: form-data; name="avatar"; filename="discord.png"
Content-Type: image/png

出于某种原因 Chrome 没有那些奇怪的字符。

注意。我刚刚注意到 Chrome 使用 form-data; name="avatar"; filename="discord.png" 而我使用 form-data; name: "avatar"; filename: "wf.png";我编辑了它 re-tested,这不是问题所在。

来自 javadoc https://docs.oracle.com/javase/8/docs/api/java/io/DataOutputStream.html#writeUTF-java.lang.String- 添加了强调:

First, two bytes are written to the output stream as if by the writeShort method giving the number of bytes to follow. This value is the number of bytes actually written out, not the length of the string. Following the length, each character of the string is output, in sequence, using the modified UTF-8 encoding for the character. ...

Data{Input,Output}Stream 不适用于文本,也不应用于文本。一般而言,MIME,尤其是多部分,主要是文本或至少是文本兼容的,以使其与传统上是文本的电子邮件兼容,尽管 HTTP 是不可知的(它支持文本和二进制)。

writeUTFdocumentation说:

First, two bytes are written to the output stream as if by the writeShort method giving the number of bytes to follow. This value is the number of bytes actually written out, not the length of the string. Following the length, each character of the string is output, in sequence, using the modified UTF-8 encoding for the character.

您在每一行的开头看到的可能是标记后续字节数的 2 个字符。

我认为 DataOutputStream 不适合您的用例。使用 s.getBytes("UTF-8").

转换 header String 后,使用 OutputStream 的普通 write(byte[] bytes) 方法