【问题标题】:Java Servlet Image Upload Corrupt (gray bottom)Java Servlet 图片上传损坏(灰底)
【发布时间】:2011-05-07 16:49:46
【问题描述】:

我们有一个接受图片上传的 servlet。有时,当上传来自我们的 iPhone 客户端(不稳定的连接)时,保存的图像最终可能会部分或完全变灰。我怀疑这是由于连接被过早终止并且 servlet 最终处理了不完整的图像。

什么是最好的补救措施?有没有办法在处理之前查看整个图像是否已上传?我应该使用 HTTP Content-Length 标头并将上传的内容与此数字进行比较吗?

谢谢!

一些上下文代码:

@Path("images/")
@POST
@Consumes("image/*")
@Produces({"application/xml", "application/json"})
public AbstractConverter postImage(byte[] imageData) {

    BufferedImage bufferedImage = null;
    try {
        bufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
    } catch (Exception e) {
    }
    if (bufferedImage == null) {
        throw new PlacesException("Image data not provided or could not be parsed", Response.Status.BAD_REQUEST);
    }

...

    BufferedImage scaledImage = ImageTool.scale(bufferedImage, imageSize);
    BufferedImage thumbnail = ImageTool.scale(bufferedImage, thumbnailSize);

    //Save image and thumbnail
    File outputfile = new File(path);
    ImageTool.imageToJpegFile(scaledImage, outputfile, 0.9f);
    File tnOutputfile = new File(thumbnailPath);
    ImageTool.imageToJpegFile(thumbnail, tnOutputfile, 0.9f);

...

public static void imageToJpegFile(RenderedImage image, File outFile, float compressionQuality) throws IOException {

    //Find a jpeg writer
    ImageWriter writer = null;
    Iterator<ImageWriter> iterator = ImageIO.getImageWritersByFormatName("jpeg");
    if (iterator.hasNext()) {
        writer = iterator.next();
    } else {
        throw new RuntimeException("No jpeg writer found");
    }


    //Set the compression quality
    ImageWriteParam params = writer.getDefaultWriteParam();
    params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    params.setCompressionQuality(compressionQuality);

    //Write to the out file
    ImageOutputStream ios = null;
    try {
        ios = ImageIO.createImageOutputStream(outFile);
        writer.setOutput(ios);
        writer.write(null, new IIOImage(image, null, null), params);

    } finally {
        writer.dispose();
        if (ios != null) {
            try {
                ios.flush();
            } catch (Exception e) {
            }
            try {
                ios.close();
            } catch (Exception e) {
            }
        }

    }
}

【问题讨论】:

    标签: java image servlets upload corruption


    【解决方案1】:

    好像上传没有正确完成。

    正如您自己指出的那样,最好的办法是使用 HTTP Content-Length 标头来检查是否已收到所有数据。如果不是,则丢弃该图像。

    【讨论】:

    • 这就是我在写这个问题时得出的结论(以及我最终做了什么)。我想没有实用的方法来检查图像的完整性、校验和或其他什么。
    • 好吧,您可以在手机上生成图像的哈希值,然后先上传该哈希值,然后在服务器上重新计算哈希值。如果存在差异,则即使长度正确,图像也会损坏(当然这不应该发生)。
    • @Oskar:我猜您可以在客户端计算校验和或其他哈希值(例如 MD5),然后将其与图像一起发送并在服务器端进行验证。但是,检查 Content-Length 应该更容易——如果您收到的字节数与预期的一样多,则可以依赖正确的数据。无论如何,TCP 已经丢弃了校验和错误的数据包。
    猜你喜欢
    • 2019-05-18
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多