我正在尝试通过HTTP发送图像。
我已经通过Chrome使用Wireshark进行了测试,以查看请求的详细信息。标头和多部分内容之间的分隔为\r\n
。
但是,我在Java中的实现似乎与\r\n
和字符0018
分开,根据FileFormat.info,字符为CANCEL
。
我正在使用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
插入在该代码示例之前,并且紧接在标头(使用HttpURLConnection.setRequestProperty
编写的标头之后),所以我不认为它们可能是问题……以防万一,您可以在第here行第64-91行中找到该代码。
这是请求正文的开头:
------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"
;我编辑并重新测试,这不是问题。
答案 0 :(得分:1)
从Javadoc https://docs.oracle.com/javase/8/docs/api/java/io/DataOutputStream.html#writeUTF-java.lang.String-开始,重点是:
首先,将两个字节写入到输出流中,就像通过writeShort方法给出要跟随的字节数一样。该值是实际写入的字节数,而不是字符串的长度。按照长度,使用修改后的字符的UTF-8编码,依次输出字符串的每个字符。 ...
Data{Input,Output}Stream
不适用于文本,也不应该用于文本。尽管HTTP是不可知的(尽管它同时支持文本和二进制),但MIME总体上来说(尤其是多部分)通常是文本,或者至少是文本兼容的,以使其与传统上是文本的电子邮件兼容。
答案 1 :(得分:1)
writeUTF
的{{3}}说:
首先,将两个字节写入输出流,就像通过writeShort方法给出要跟随的字节数一样。该值是实际写入的字节数,而不是字符串的长度。按照该长度,使用修改后的字符的UTF-8编码,依次输出字符串的每个字符。
在每一行的开头看到的可能是2个字符,它们表示要跟随的字节数。
我认为DataOutputStream
对于您的用例而言并不理想。用write(byte[] bytes)
转换标题OutputStream
后,请使用String
的普通s.getBytes("UTF-8")
方法。