2010-11-10 32 views
1

Nous avons une servlet qui accepte les téléchargements d'images. Parfois, lorsque les téléchargements proviennent de notre client iPhone (connexion floconneuse) l'image enregistrée peut finir par être partiellement ou complètement grise. Je suppose que cela est dû au fait que la connexion est prématurément terminée et que le servlet finit par traiter une image incomplète.Java Servlet Téléchargement d'images corrompu (fond gris)

Quel est le meilleur remède pour cela? Existe-t-il un moyen de voir si l'image entière a été téléchargée avant le traitement? Dois-je utiliser l'en-tête HTTP Content-Length et comparer ce qui est téléchargé avec ce numéro?

Merci!

Une partie du code pour le contexte:

@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) { 
      } 
     } 

    } 
} 

Répondre

0

Il semble que le téléchargement n'a pas terminé correctement.

Comme vous l'avez indiqué vous-même, le mieux est d'utiliser l'en-tête HTTP Content-Length pour vérifier que toutes les données ont bien été reçues. Si ce n'est pas le cas, jetez l'image.

+0

C'est ce que j'ai conclu en écrivant la question (et ce que j'ai fini par faire). Je suppose qu'il n'y a aucun moyen pratique de vérifier l'intégrité d'une image, vérifier les sommes ou quoi que ce soit. – Oskar

+0

Eh bien, vous pouvez produire un hachage de l'image sur le téléphone et télécharger le premier et recalculer le hachage sur le serveur. S'il y a une différence, alors l'image est corrompue même si la longueur est correcte (bien sûr, cela ne devrait pas arriver). – Jaydee

+0

@Oskar: Je suppose que vous pouvez calculer une somme de contrôle ou un autre hachage (par exemple un MD5) dans le client, puis l'envoyer avec l'image et la vérifier du côté serveur. Cependant, vérifier la longueur du contenu devrait être plus facile - si vous recevez autant d'octets que prévu, vous pouvez compter sur les données correctes. TCP rejette déjà les paquets avec une mauvaise somme de contrôle de toute façon. – Grodriguez