【发布时间】:2015-08-18 10:15:17
【问题描述】:
我有一个问题困扰了我整整一个星期,我走到了死胡同。
这是场景:我在 Java Spring Controller 中有一个方法来处理 HTTP POST 请求。 POST 请求包含一张图片。扭曲的是图片不是作为多部分请求发送的,它是在 RequestBody 中发送的(注意答案说要改变发送图片的方式:我无权访问或不可能这样做,我必须处理什么我有)。
所以我使用请求中的输入流来提取图片。然后我打开一个输出流,然后写入文件,同时从输入流中读取。
InputStream is = request.getInputStream();
OutputStream os = new FileOutputStream(new File("D:\\M\\" + request.getHeader("Content-Location").toString()));
int x;
while ((x = is.read()) != -1) {
os.write(x);
os.flush();
}
os.close();
没有什么花哨的,只是在你阅读时写的普通的老字号,一个字节一个字节。
问题是图片显示为jpeg(意料之中),但是打不开(我试过多个查看器,结果一样):
name_of_pic.jpg 解码错误!不是 JPEG 文件:以 0xbd 0xef 开头
然后我说好吧,让我们尝试另一种方式或输出流来写入图片。以下所有代码都得到了相同的结果。
//alternative way1
DataInputStream dis = new DataInputStream(is);
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File("D:\\M\\" + request.getHeader("Content-Location").toString())));
while(dis.available()>0){
int b = dis.read();//also tried with readByte, readUnsignedByte.. got 0kb file
dos.write(b);
dos.flush();
}
dos.close();
//alternative way2
IOUtils.copy(is, os);
//alternative way3
int len = 0;
byte[] buffer = new byte[8 * 1024];
while ((len = is.read(buffer, 0, buffer.length)) > 0) {
for (int i = 0; i < buffer.length; i++) {
System.out.print(buffer[i]);
}
System.out.println();
os.write(buffer, 0, len);
}
os.flush();
os.close();
所以我查看了调试器中的 requestBody 并将其与图片中的内容进行了比较。存储在 requestBody 中的值和存储在图片中的值存在差异(在我将其写入文件系统之后)。
这张图显示了requestBody中的几个第一个值:http://prntscr.com/7cuiw5
这就是图片在十六进制值中的样子(使用 irfanview 十六进制编辑器): http://prntscr.com/7culcn
很明显,我得到的和我写下的有所不同。
问题是哪里出错了?读取int的输出流有问题吗?或者可能是从十六进制到整数/字节的转换?
无论如何,我真的很喜欢这个。任何帮助都将不胜感激。很抱歉我不能直接发布图片(没有那么多声誉)。
【问题讨论】:
-
你解决问题了吗?
-
@Qinjie 是的,因为我记得问题在于 http servlet 请求链中的自定义过滤器正在改变请求正文。删除了自定义过滤器,代码按预期工作。
标签: java spring image file-io outputstream