如何检查上传的文件是图像还是其他文件?
在我的Web应用程序中,我有一个图像上传模块。我想检查上传的文件是图像文件还是任何其他文件。我在服务器端使用Java。
图像被读取为java,然后我用它写到磁盘BufferedImage
ImageIO.write()
我该如何检查 ,它是否真的是图像还是其他东西?BufferedImage
任何建议或链接将不胜感激。
在我的Web应用程序中,我有一个图像上传模块。我想检查上传的文件是图像文件还是任何其他文件。我在服务器端使用Java。
图像被读取为java,然后我用它写到磁盘BufferedImage
ImageIO.write()
我该如何检查 ,它是否真的是图像还是其他东西?BufferedImage
任何建议或链接将不胜感激。
我假设你在 servlet 上下文中运行它。如果仅基于文件扩展名检查内容类型是负担得起的,则使用 ServletContext#getMimeType()
获取 mime 类型(内容类型)。只需检查它是否以 开头。image/
String fileName = uploadedFile.getFileName();
String mimeType = getServletContext().getMimeType(fileName);
if (mimeType.startsWith("image/")) {
// It's an image.
}
默认的 mime 类型在所讨论的 servletcontainer 中定义。例如,在Tomcat中,它位于.您可以在 Web 应用程序中扩展/覆盖它,如下所示:web.xml
/conf/web.xml
/WEB-INF/web.xml
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
但这并不妨碍您通过更改文件扩展名来欺骗您的用户。如果您也想涵盖这一点,那么您也可以根据实际文件内容确定哑剧类型。如果只检查BMP,GIF,JPG或PNG类型(但不是TIF,PSD,SVG等)是负担得起的,那么你可以直接将其提供给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.
}
}
但是,如果您还想涵盖更多图像类型,请考虑使用第三方库,该库通过嗅探文件头来完成所有工作。例如JMimeMagic或Apache Tika,它们同时支持BMP,GIF,JPG,PNG,TIF和PSD(但不支持SVG)。Apache Batik支持SVG。下面的示例使用 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.
}
}
如有必要,您可以使用组合并超过一个和另一个。
也就是说,您不一定需要将上传的图像保存到磁盘。只需将获取的直接写入一个或任何类似于通常的Java IO方式就足够了(另请参阅在servlet应用程序中保存上传文件的推荐方法):ImageIO#write()
InputStream
Path
OutputStream
FileOutputStream
try (InputStream input = uploadedFile.getInputStream()) {
Files.copy(input, new File(uploadFolder, fileName).toPath());
}
当然,除非您想收集一些图像信息,例如其尺寸和/或想要操纵它(裁剪/调整大小/旋转/转换/等)。
在我的情况下,我使用了org.apache.commons.imaging.Imaging。下面是一段代码示例,用于检查图像是否为 jpeg 图像。如果上传的文件不是图像,它将引发 ImageReadException。
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
}