Spring文件上传内容类型验证,总是octet-stream



我正在尝试在我的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的包装器。

我然后使用邮差发送请求与form-data'file'=<filename.pdf>

上面printlns中的内容类型总是8字节流。无论我发送什么类型的文件(png, pdf等),它总是八字节流。如果我特别将application/pdf设置为Postman中的内容类型头,则FileDTO中的MultipartFile最终为空。

问题是,我的弹簧控制器方法是否有问题,或者请求只是没有被邮差正确构建?

如果邮差不能得到内容类型正确,我可以期望实际的客户端应用程序正确地设置内容类型为pdf吗?

您是否尝试过Apache Tika库来检测上传文件的mime类型?

Kotlin代码示例

private fun getMimeType(file: File) = Tika().detect(file)

FileDTO将包装multipart/form-data的整个内容,所以如果您上传的文件输入名为file,您的DTO/Form/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();
    }
}

我希望它适合你。

通常文件上传是用MIME多部分消息格式包装的,因此HTTP头中的内容类型只能是multipart/form-data,并且您可以在每个部分中分别指定每个字段(包括文件)的MIME类型。

在Postman中似乎没有办法为多部分字段指定MIME类型,所以我只能假设这是一个缺失的功能。

我以前有过这个问题,使用以下修复了这个问题:

Files.probeContentType(path)

返回格式类型的字符串。这似乎是我尝试过的最可靠的解决方案。

相关内容

  • 没有找到相关文章

最新更新