我正在尝试在Restful Spring Boot应用程序中实现pdf文件上传。
我有以下方法;
@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只是MultipartFile的包装。
然后我使用Postman通过form-data
正文'file'=<filename.pdf>
上面的printlns中的内容类型总是八位字节流。无论我发送什么类型的文件(png,pdf等),它总是八位字节流。如果我在Postman中专门将application/pdf
设置为Content-Type标头,则FileDTO中的MultipartFile最终为null。
问题是,我的Spring Controller方法有问题,还是Postman没有正确构建请求?
如果邮递员无法正确获取内容类型,我是否可以期望实际客户端应用将内容类型正确设置为pdf?
答案 0 :(得分:2)
您是否尝试过Apache Tika库来检测上传文件的mime类型?
Kotlin中的代码示例
private fun getMimeType(file: File) = Tika().detect(file)
答案 1 :(得分:0)
通常,文件上传以MIME多部分邮件格式包装,因此HTTP标头中的内容类型只能是multipart/form-data
,并且您在每个部分中分别指定每个字段(包含文件)的MIME类型。 / p>
似乎在Postman中,没有办法为多部分字段指定MIME类型,所以我只能假设它是一个缺少的功能。
答案 2 :(得分:0)
FileDTO
将包含multipart/form-data
的全部内容,因此,如果您上传的文件输入名为file
,则您的DTO /表单/ POJO应与以下内容相同:
class FileDTO{
@NotNull
private String anotherAttribute;
@NotNull
private MultipartFile file;
//Getters and Setters
}
因此,您还应将控制器功能更改为
@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 ...
}
要使用此类功能,您应该使用MVC配置文件中的StandardServletMultipartResolver
。类似的东西:
@EnableWebMvc
@Configuration
@ComponentScan("mypackage.web.etc")
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
我希望它适合你。
答案 3 :(得分:0)
我以前遇到过这个问题,使用以下方法解决了这个问题:
Files.probeContentType(path)
上面返回了一个格式类型的字符串。似乎是我尝试过的最可靠的解决方案。