[英]Spring file upload content type validation, always octet-stream?
I'm trying to implement pdf file uploading in my Restful Spring Boot application.我正在尝试在我的 Restful Spring Boot 应用程序中实现 pdf 文件上传。
I have the following method;我有以下方法;
@RequestMapping(value = FILE_URL, method = RequestMethod.POST)
public ResponseDTO submitPDF(
@ModelAttribute("file") FileDTO file) {
MediaType mediaType = MediaType.parseMediaType(file.getFile().getContentType());
System.out.println(file.getFile().getContentType());
System.out.println(mediaType);
System.out.println(mediaType.getType());
if(!"application/pdf".equals(mediaType.getType())) {
throw new IllegalArgumentException("Incorrect file type, PDF required.");
}
... more code here ...
}
FileDTO is just a wrapper around MultipartFile. FileDTO 只是 MultipartFile 的一个包装器。
I'm then using Postman to POST the request with form-data
body 'file'=<filename.pdf>
然后我使用 Postman 用
form-data
主体'file'=<filename.pdf>
POST 请求
The content type in the printlns above is ALWAYS octet-stream.上面 printlns 中的内容类型始终是八位字节流。 No matter what type of file I send in (png, pdf, etc) its always octet stream.
无论我发送什么类型的文件(png、pdf 等),它始终是八位字节流。 If I specifically set
application/pdf
as Content-Type header in Postman the MultipartFile within FileDTO ends up as null.如果我在 Postman 中专门将
application/pdf
设置为 Content-Type 标头,则 FileDTO 中的 MultipartFile 最终为空。
Question is, is there something wrong with my Spring Controller method, or is the request just not being built correctly by Postman?问题是,我的 Spring Controller 方法有问题,还是 Postman 没有正确构建请求?
If Postman can't get the Content-Type right, can I expect actual client apps to properly set content type to pdf?如果 Postman 无法正确获取 Content-Type,我是否可以期望实际的客户端应用程序将内容类型正确设置为 pdf?
Have you tried Apache Tika library for detecting mime types of uploaded file?您是否尝试过Apache Tika库来检测上传文件的 MIME 类型?
Code Example in Kotlin Kotlin 中的代码示例
private fun getMimeType(file: File) = Tika().detect(file)
Normally file uploads are wrapped in a MIME multipart message format, so the content type in the HTTP header can only be multipart/form-data
and you specify the MIME type of each field (include files) separately in each part.通常文件上传被包裹在一个 MIME 多部分消息格式中,所以 HTTP 头中的内容类型只能是
multipart/form-data
并且您在每个部分中单独指定每个字段(包含文件)的 MIME 类型。
It seems in Postman there's no way to specify the MIME type for a multi-part field so I can only assume it's a missing feature.在 Postman 中似乎无法为多部分字段指定 MIME 类型,所以我只能假设它是一个缺失的功能。
The FileDTO
will wrap the whole content of the multipart/form-data
so if your uploaded file input is named file
, your DTO/Form/POJO should be alike to: FileDTO
将包装multipart/form-data
的全部内容,因此如果您上传的文件输入名为file
,您的 DTO/Form/POJO 应该类似于:
class FileDTO{
@NotNull
private String anotherAttribute;
@NotNull
private MultipartFile file;
//Getters and Setters
}
Therefore you should also change your controller function to因此,您还应该将控制器功能更改为
@RequestMapping(value = FILE_URL, method = RequestMethod.POST)
public ResponseDTO submitPDF(@ModelAttribute FileDTO fileWrapper) {
MediaType mediaType = MediaType.parseMediaType(fileWrapper.getFile().getContentType());
System.out.println(fileWrapper.getFile().getContentType());
System.out.println(mediaType);
System.out.println(mediaType.getType());
if(!"application/pdf".equals(mediaType.getType())) {
throw new IllegalArgumentException("Incorrect file type, PDF required.");
}
... more code here ...
}
To use this sort of functions you should use the StandardServletMultipartResolver
in your MVC configurer file.要使用此类函数,您应该在 MVC 配置器文件中使用
StandardServletMultipartResolver
。 Something like:就像是:
@EnableWebMvc
@Configuration
@ComponentScan("mypackage.web.etc")
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
I hope it suites you.我希望它适合你。
I've had this issue before, using the following fixed the issue:我以前遇到过这个问题,使用以下方法解决了这个问题:
Files.probeContentType(path)
The above returns a string with the format type.上面返回一个具有格式类型的字符串。 Seems to be the most reliable solution I've tried.
似乎是我尝试过的最可靠的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.