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é.

25
demandé sur BalusC 2010-11-13 01:39:35

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.

87
répondu BalusC 2017-05-23 12:18:21

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
    }
3
répondu gagan bopanna 2016-02-17 15:23:29

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
2
répondu gcstang 2016-02-29 20:19:01