Comment vérifier un fichier téléchargé qu'il s'agisse d'une image ou d'un autre fichier?
dans mon application web, j'ai un module de téléchargement d'image. Je veux vérifier le fichier téléchargé si c'est un fichier image ou tout autre fichier. Je suis à l'aide de Java côté serveur.
  l'image est lue comme  BufferedImage  en java et ensuite je l'écris sur disque avec  ImageIO.write()   
  Comment puis-je vérifier le  BufferedImage  , que ce soit vraiment une image ou autre chose?  
toute suggestion ou lien serait apprécié.
3 réponses
  je suppose que vous exécutez ceci dans un contexte de servlet. S'il est abordable de vérifier le type de contenu basé uniquement sur l'extension du fichier, alors utilisez     ServletContext#getMimeType()     pour obtenir le type mime (Type de contenu). Vérifiez si ça commence par  image/  .   
String fileName = uploadedFile.getFileName();
String mimeType = getServletContext().getMimeType(fileName);
if (mimeType.startsWith("image/")) {
    // It's an image.
}
 les types mime par défaut sont définis dans le web.xml  du servletcontainer en question. Dans Tomcat par exemple, il est situé dans  /conf/web.xml  . Vous pouvez étendre/remplacer dans le  /WEB-INF/web.xml  de votre webapp comme suit:  
<mime-mapping>
    <extension>svg</extension>
    <mime-type>image/svg+xml</mime-type>
</mime-mapping>
  mais cela ne vous empêche pas des utilisateurs qui vous dupent en changeant l'extension du fichier. Si vous souhaitez couvrir cela aussi, alors vous pouvez également déterminer le type mime basé sur le contenu du fichier    actual   . S'il est abordable de vérifier uniquement pour les types BMP, GIF, JPG ou PNG (mais pas TIF, PSD, SVG, etc), alors vous pouvez simplement l'alimenter directement à      ImageIO#read()    et vérifier s'il ne jette pas une exception.  
try (InputStream input = uploadedFile.getInputStream()) {
    try {
        ImageIO.read(input).toString();
        // It's an image (only BMP, GIF, JPG and PNG are recognized).
    } catch (Exception e) {
        // It's not an image.
    }
}
mais si vous souhaitez couvrir plus de types d'image aussi bien, alors envisagez d'utiliser une bibliothèque tierce partie qui fait tout le travail en reniflant le en-têtes de fichier . Par exemple JMimeMagic ou Apache Tika qui supportent à la fois BMP, GIF, JPG, PNG, TIF et PSD (mais pas SVG). Apache Batik prend en charge le format SVG. L'exemple ci-dessous utilise JMimeMagic:
try (InputStream input = uploadedFile.getInputStream()) {
    String mimeType = Magic.getMagicMatch(input, false).getMimeType();
    if (mimeType.startsWith("image/")) {
        // It's an image.
    } else {
        // It's not an image.
    }
}
vous pouvez si nécessaire utiliser des combinaisons et l'emporter sur l'une et l'autre.
 cela dit, vous n'avez pas nécessairement besoin de ImageIO#write()  pour sauvegarder l'image chargée sur le disque. Il suffit d'écrire le  InputStream  obtenu directement à un  Path  ou n'importe quel  OutputStream  comme  FileOutputStream  la façon habituelle Java IO est plus que suffisant (voir aussi    méthode recommandée pour enregistrer téléchargé fichiers dans une application servlet    ):  
try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, new File(uploadFolder, fileName).toPath());
}
sauf si vous souhaitez recueillir des informations d'image comme ses dimensions et/ou que vous voulez les manipuler (recadrer/redimensionner/tourner/convertir/etc) Bien sûr.
j'ai utilisé org.Apache.commun.l'imagerie.Imagerie dans mon cas. Voici un exemple de code pour vérifier si une image est une image jpeg ou non. Il lance ImageReadException si le fichier téléchargé n'est pas une image.
    try {
        //image is InputStream
        byte[] byteArray = IOUtils.toByteArray(image);
        ImageFormat mimeType = Imaging.guessFormat(byteArray);
        if (mimeType == ImageFormats.JPEG) {
            return;
        } else {
            // handle image of different format. Ex: PNG
        }
    } catch (ImageReadException e) {
        //not an image
    }
il est intégré dans le JDK et nécessite simplement un flux avec support pour
byte[] data = ;
InputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
String mimeType = URLConnection.guessContentTypeFromStream(is);
//...close stream