如何检查上传的文件是否是图像或其他文件? [英] How to check a uploaded file whether it is a image or other file?
问题描述
在java中的图像读取为 BufferedImage
,然后我写它到 ImageIO.write()
如何检查 h2_lin>解决方案 BufferedImage <
$ b
我假设你正在servlet上下文中运行它。如果根据文件扩展名检查内容类型是否合理,请使用 ServletContext#getMimeType()
来获取MIME类型(内容类型)。只要检查它是否以 image /
开头。
String fileName = uploadedFile.getFileName();
String mimeType = getServletContext()。getMimeType(fileName);
if(mimeType.startsWith(image /)){
//这是一张图片。
$ b 缺省的mime类型在 web中定义。有问题的servletcontainer的xml
。例如Tomcat,它位于 /conf/web.xml
中。您可以在webapp的 /WEB-INF/web.xml
中扩展/覆盖它,如下所示:
< mime-mapping>
< extension> svg< / extension>
< mime-type> image / svg + xml< / mime-type>
< / mime-mapping>
但是,这并不妨碍您通过更改文件扩展名来欺骗您。如果您想要介绍这一点,那么您也可以根据 文件内容来确定MIME类型。如果只检查BMP,GIF,JPG或PNG类型(而不是TIF,PSD,SVG等),那么您可以直接将其提供给 ImageIO#read()
,并检查它是否没有抛出异常。
try(InputStream input = uploadedFile.getInputStream()) {
try {
ImageIO.read(input).toString();
//这是一张图片(只识别BMP,GIF,JPG和PNG)。
} catch(Exception e){
//这不是图像。
$ b $ p $但是如果你想要覆盖更多的图片类型也可以考虑使用第三方库,通过嗅探文件头来完成所有工作。例如 JMimeMagic 或 Apache Batik 支持SVG。下面的例子使用了JMimeMagic:
$ $ p $ $ $ $ c $ try $ getMagicMatch(input,false).getMimeType();
if(mimeType.startsWith(image /)){
//这是一张图片。
} else {
//这不是图片。
$ b $ p
$ b 如果需要,可以使用组合并超过其他的。
也就是说,您不一定需要 ImageIO#write()
来将上传的图像保存到磁盘。只需将获得的 InputStream
直接写入 Path
或任何 OutputStream
像 FileOutputStream
通常的Java IO方式已经足够了(另见将上传的文件保存在servlet应用程序中的推荐方法): (InputStream input = uploadedFile.getInputStream()){
Files.copy(input,new File(uploadFolder,fileName).toPath());除非你想收集一些图像信息,如尺寸和/或图像想要操纵它(裁剪/调整大小/旋转/转换/等)当然。
In my web application I have an image uploading module. I want to check the uploaded file whether it's an image file or any other file. I am using Java in server side.
The image is read as BufferedImage
in java and then I am writing it to disk with ImageIO.write()
How shall I check the BufferedImage
, whether it's really an image or something else?
Any suggestions or links would be appreciated.
解决方案 I'm assuming that you're running this in a servlet context. If it's affordable to check the content type based on just the file extension, then use ServletContext#getMimeType()
to get the mime type (content type). Just check if it starts with image/
.
String fileName = uploadedFile.getFileName();
String mimeType = getServletContext().getMimeType(fileName);
if (mimeType.startsWith("image/")) {
// It's an image.
}
The default mime types are definied in the web.xml
of the servletcontainer in question. In for example Tomcat, it's located in /conf/web.xml
. You can extend/override it in the /WEB-INF/web.xml
of your webapp as follows:
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
But this doesn't prevent you from users who are fooling you by changing the file extension. If you'd like to cover this as well, then you can also determine the mime type based on the actual file content. If it's affordable to check for only BMP, GIF, JPG or PNG types (but not TIF, PSD, SVG, etc), then you can just feed it directly to ImageIO#read()
and check if it doesn't throw an 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.
}
}
But if you'd like to cover more image types as well, then consider using a 3rd party library which does all the work by sniffing the file headers. For example JMimeMagic or Apache Tika which support both BMP, GIF, JPG, PNG, TIF and PSD (but not SVG). Apache Batik supports SVG. Below example uses 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.
}
}
You could if necessary use combinations and outweigh the one and other.
That said, you don't necessarily need ImageIO#write()
to save the uploaded image to disk. Just writing the obtained InputStream
directly to a Path
or any OutputStream
like FileOutputStream
the usual Java IO way is more than sufficient (see also Recommended way to save uploaded files in a servlet application):
try (InputStream input = uploadedFile.getInputStream()) {
Files.copy(input, new File(uploadFolder, fileName).toPath());
}
Unless you'd like to gather some image information like its dimensions and/or want to manipulate it (crop/resize/rotate/convert/etc) of course.
这篇关于如何检查上传的文件是否是图像或其他文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!