【问题标题】:Extracting image from a request body results with a corrupted image (Spring MVC)从请求正文中提取图像导致图像损坏(Spring MVC)
【发布时间】: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


【解决方案1】:

当您在记事本中打开图像时,您会在顶部和底部看到一些额外的代码。

------------------119202331112770

内容配置:表单数据;名称=“文件”;文件名="..gif"

内容类型:图片/gif

如果您想查看您的图片,必须删除此代码。 这些代码存在于 post 方法的主体中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2021-02-23
    • 2013-06-02
    • 1970-01-01
    • 2013-12-26
    相关资源
    最近更新 更多