如何检查上传的文件是否是图像或其他文件?
在我的web应用程序中,我有一个图像上传模块。 我想检查上传的文件是否是图像文件或任何其他文件。 我在服务器端使用Java。
该图像读取为BufferedImage
在Java中,然后我写它与磁盘ImageIO.write()
我应该如何检查BufferedImage
,不pipe它是一个图像还是其他的东西?
任何build议或链接,将不胜感激。
我假设你在servlet上下文中运行这个。 如果根据文件扩展名检查内容types是否合理,则使用ServletContext#getMimeType()
获取MIMEtypes(内容types)。 只要检查它是否开始与image/
。
String fileName = uploadedFile.getFileName(); String mimeType = getServletContext().getMimeType(fileName); if (mimeType.startsWith("image/")) { // It's an image. }
默认的MIMEtypes在servletcontainer的web.xml
中定义。 例如Tomcat,它位于/conf/web.xml
。 您可以在/WEB-INF/web.xml
应用程序的/WEB-INF/web.xml
中扩展/覆盖它,如下所示:
<mime-mapping> <extension>svg</extension> <mime-type>image/svg+xml</mime-type> </mime-mapping>
但是,这并不能阻止你通过改变文件扩展名来欺骗你的用户。 如果您想要覆盖这一点,那么您也可以根据实际的文件内容来确定MIMEtypes。 如果只检查BMP,GIF,JPG或PNGtypes(但不包括TIF,PSD,SVG等),那么您可以直接将它提供给ImageIO#read()
并检查它是否不抛出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. } }
但是,如果您想要覆盖更多的图片types,请考虑使用第三方库,通过嗅探文件头来完成所有工作。 例如支持BMP,GIF,JPG,PNG,TIF和PSD(但不支持SVG)的JMimeMagic或Apache Tika 。 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. } }
你可以在必要时使用组合,并胜过其中一个。
也就是说,您不一定需要ImageIO#write()
将上传的图像保存到磁盘。 只需将获得的InputStream
直接写入Path
或任何OutputStream
如FileOutputStream
,通常的Java IO方式就足够了(另请参阅将上载的文件保存在servlet应用程序中的推荐方法 ):
try (InputStream input = uploadedFile.getInputStream()) { Files.copy(input, new File(uploadFolder, fileName).toPath()); }
除非你想收集一些像尺寸的图像信息和/或想操纵它(裁剪/resize/旋转/转换/等),当然。
我用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 }
这是内置到JDK中,只需要一个stream支持
byte[] data = ; InputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); String mimeType = URLConnection.guessContentTypeFromStream(is); //...close stream