如何知道用户在表单中提交的图像类型?

时间:2010-07-20 21:43:11

标签: java google-app-engine servlets

我允许我的用户上传头像图片(谷歌应用引擎,java)。我不知道他们上传时的图像类型。我只是在提交表格中存储他们给我的任何内容。我在这里关注这个例子:

http://code.google.com/appengine/docs/python/images/usingimages.html

有没有办法在存储之前检查它是什么图像类型?例如,如果他们提交了一个文本文件,我不想接受它。

另外,如何在返回图像时更改内容类型?我需要知道它是什么图像类型,才能正确设置内容类型?:

 resp.setHeader("Content-Type", "image/jpg");   

我正在使用java,

由于

3 个答案:

答案 0 :(得分:3)

通常,如果您使用的是基于浏览器的文件上传,则表单数据将包含文件名和从文件扩展名推断的内容类型。但是,这并不能保证用户没有上传具有误导性扩展名的文件。要验证内容类型,您可以使用Images service

Image img = ImagesServiceFactory.makeImage(uploadedBytes);
String contentType = "image/" + img.getFormat().toString().toLowerCase();

支持的类型有BMP,GIF,ICO,JPEG,PNG和TIFF。其他任何事都应该失败。

这可能不言而喻,但您应该仅在上传时检查内容类型,然后将其与图像一起存储;不要调用图像服务来查找每个下载请求的类型。

答案 1 :(得分:1)

如果根据文件扩展名检查内容类型,则可以使用ServletContext#getMimeType()

String mimeType = getServletContext().getMimeType(filename);

if (mimeType.startsWith("image")) {
    // It's an image.
}

默认的mime类型在相关servletcontainer的web.xml中定义。例如Tomcat,它位于/conf/web.xml。您可以在网络应用的/WEB-INF/web.xml中扩展/覆盖它,如下所示:

<mime-mapping>
    <extension>svg</extension>
    <mime-type>image/svg-xml</mime-type>
</mime-mapping>

但这并不能阻止您通过更改文件扩展名来欺骗您的用户。如果您还要覆盖此内容,则还可以根据实际文件内容确定mime类型。你可以通过嗅探file headers来做到这一点。考虑使用第三方库来完成所有工作。我发现JMimeMagic对此很有用。您可以按如下方式使用它:

String mimeType = Magic.getMagicMatch(uploadedFile, false).getMimeType();

为了能够回传图像,你可以设置响应内容类型,结果为ServletContext#getMimeType()(在上传过程中不要忘记确认这等于JMimeMagic返回的内容,对于案例这一点)。

response.setContentType(getServletContext().getMimeType(file.getName()));

答案 2 :(得分:0)

为什么不直接从文件名中获取扩展名,并使用它来确定它是什么类型的图像,并从中找出mime类型?

另一种方法是使用谷歌应用引擎图像处理API使用不同的文件类型打开您的图像,并检查哪一个不会导致错误。这将是CPU密集型但更可靠。