当时需要开发一个功能,管理员可以上传一个包含不良词语的文本文件。系统利用这些词语实时检查用户提交的内容。上传的文件需要遵循特定的格式。
为了防止用户上传文本文件以外的文件,我们可以在前端进行操作。
<input type="file" accept="text/plain" />
这样,用户只需在文件选择窗口中选择一个文本文件即可。然而,为了确保系统安全,仅仅在界面上阻止用户是不够的。有必要在后台重新验证上传的文件,看看用户是否上传了文本文件。我们需要解决的问题是确定用户上传文件的实际类型。
开始
说明上述问题,我们将建立一个演示系统,前端使用 React.js,后端使用 Java/Spring Boot。
我们的界面非常简单,由一个输入[type=file]和一个上传所选文件的按钮组成。选择文件时,用户界面将显示浏览器确定的 MIME 类型。上传文件后,系统将返回后台确定的 MIME 类型。所有源代码都在这里。此外,还要准备一些文件,以测试系统判断是否正确。
准备 3 个扩展名正确的文件,然后复制这些文件并重命名:
real.png -> fake.txt
real.jpg -> fake.zip
real.svg -> fake.docx
后台文件类型确定
项目的后台系统使用 Spring Boot 以 Java 编写。还实现了一个控制器,用于接收用户的上传请求。
@Slf4j
@RestController
public class UploadController {
@PostMapping(path = "/check-file-type", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity < Response > checkFileType(@RequestPart MultipartFile file) {
// to be implemented
}
}
以及将结果返回给用户的响应
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Response {
private int status;
private String message;
private String mimeType;
public Response(String mimeType) {
this.status = HttpStatus.OK.value();
this.message = "Successful";
this.mimeType = mimeType;
}
}
使用用户代理定义的 MIME 类型
当从 input[type=file] 中选择文件时,文件类型已由浏览器(用户代理)根据 MIME 类型格式确定,然后通过 Content-Type 请求头传输到后端。因此,控制器参数中的 MultipartFile 类已经包含了文件类型的信息。
现在,您可以使用 getContentType() 根据 MIME 类型确定文件类型。
@PostMapping(path = "/check-file-type", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity < Response > checkFileType(@RequestPart MultipartFile file) {
String mimeType = file.getContentType();
return ResponseEntity.ok(new Response(mimeType));
}
让我们测试一下上面准备的文件
就文件 real.png 而言,用户代理通过 .png 扩展名识别出了正确的 MIME 类型。但对于 fake.zip 文件,用户代理无法正确识别其文件类型为 JPG,而是通过 .zip 扩展名来确定。因此,当用户有意更改文件名和扩展名时,依赖客户端定义的 MIME 类型可能会有一些风险。每种文件类型都有不同的规范,存储方式也不同,因此如果要确定文件的确切类型,就需要读取该文件的内容。
MIME 类型和确定文件类型的一些方法 MIME 类型(多用途 Internet 邮件扩展)是一种定义文档、文件或字节集的性质和格式的标准。它在 IETF 的 RFC 6838中进行了定义和标准化。MIME 类型的结构包括类型和子类型:
类型/子类型 示例:text/plain、application/zip、...
详细说明
类型是数据类型所属的一般类别,如视频或文本。 子类型决定所分类的确切数据类型。例如对于文本类型,我们可以有 plain(纯文本)、html(HTML 源代码)或 calendar(iCalendar .ics 格式)等子类型。一般来说,MIME 类型是分配给文件类型的名称,用于确定传输数据的内容类型,以及基于该类型的应用程序的相应行为。根据 MIME 类型,我们可以确定文件类型,那么如何从一个文件中识别其 MIME 类型呢?要确定 MIME 类型,我们需要读取其内容。每种文件类型都会有不同的存储方式,比如 ZIP 文件的文件规范就像这里一样。但仍有一些共同特征可用于识别。 文件签名是存储在文件开头的模式字节(也称为神奇数字或神奇字节),用于识别文件的内容和格式。下表列出了一些常用格式的文件签名(在此查看一些文件签名)。
除了使用文件签名外,有时还需要读取文件内容来找到确切的文件类型。例如,SVG 格式本质上是 XML。因此,要确定它,除了需要读取魔法数字来确定 XML 格式外,还需要读取里面更多的内容,才能正确确定 SVG 格式。
其他一些格式,如 Apple iWork,实际上是 Zip 文件中 XML 文件的集合。此时,Zip 文件负责制作包含 XML 文件的容器。由于需要解压其中的内容,文件类型识别变得更加困难。
使用 Apache Tika
确定 MIME 类型 在 Java 系统中,可以使用 Apache Tika 提取信息并确定文件数据的确切格式。Apache Tika 可根据以下几个标准确定文件的数据格式:
魔数(Magic number)
文件名扩展名(File name extension):部分基于文件扩展名
从互联网下载文件的元数据(Metadata)
定义容器及其内容(container)
要在 Maven 项目中使用 Tika,可以在 pom.xml 中添加依赖关系:
<dependency>
<groupId>org.apache.tik
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)