如何检查上传的文件是图像还是其他文件?

问题描述 投票:27回答:3

在我的Web应用程序中,我有一个图像上传模块。我想检查上传的文件是图像文件还是其他文件。我在服务器端使用Java。

图像在Java中读为BufferedImage,然后用ImageIO.write()将其写入磁盘

我应该如何检查BufferedImage,究竟是图像还是其他?

任何建议或链接将不胜感激。

java image servlets file-upload bufferedimage
3个回答
92
投票

我假设您正在servlet上下文中运行它。如果仅根据文件扩展名检查内容类型是可以承受的,则使用ServletContext#getMimeType()获取mime类型(内容类型)。只需检查它是否以ServletContext#getMimeType()开头。

image/

默认的mime类型在相关的servlet容器的String fileName = uploadedFile.getFileName(); String mimeType = getServletContext().getMimeType(fileName); if (mimeType.startsWith("image/")) { // It's an image. } 中定义。例如在Tomcat中,它位于web.xml中。您可以按以下步骤在Web应用程序的/conf/web.xml中扩展/覆盖它:

/WEB-INF/web.xml

但是这不会阻止您通过更改文件扩展名来欺骗您。如果您也想解决这个问题,那么您还可以根据actual文件内容确定MIME类型。如果仅检查BMP,GIF,JPG或PNG类型(而不是TIF,PSD,SVG等)负担得起,则可以直接将其直接馈送到<mime-mapping> <extension>svg</extension> <mime-type>image/svg+xml</mime-type> </mime-mapping> 并检查它是否不会引发异常。 >

ImageIO#read()

但是如果您还想涵盖更多图像类型,请考虑使用第三方库,该库通过嗅探ImageIO#read()来完成所有工作。例如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. } } file headers同时支持BMP,GIF,JPG,PNG,TIF和PSD(但不支持SVG)。 JMimeMagic支持SVG。下面的示例使用JMimeMagic:

Apache Tika

如果有必要,您可以组合使用并且胜过一个。

就是说,您不一定需要Apache Batik才能将上传的图像保存到磁盘。只需将获得的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. } } 直接写到ImageIO#write()或类似InputStream的任何Path上,通常的Java IO方法就足够了(另请参见OutputStream):

FileOutputStream

当然,除非您想收集一些图像信息,例如其尺寸和/或想要对其进行操作(裁剪/调整大小/旋转/转换/等)。


4
投票

我使用的是Recommended way to save uploaded files in a servlet application。下面是一段示例代码,用于检查图像是否为jpeg图像。如果上传的文件不是图像,则会抛出ImageReadException。


2
投票

这内置在JDK中,只需要一个支持]的流即可。

org.apache.commons.imaging.Imaging
© www.soinside.com 2019 - 2024. All rights reserved.