3

我正在尝试在我的 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 中的内容类型是 ALWAYS octet-stream。无论我发送什么类型的文件(png、pdf 等),它始终是八位字节流。如果我application/pdf在 Postman 中专门设置为 Content-Type 标头,则 FileDTO 中的 MultipartFile 最终为空。

问题是,我的 Spring Controller 方法有问题,还是 Postman 没有正确构建请求?

如果 Postman 无法正确获取 Content-Type,我可以期望实际的客户端应用程序将内容类型正确设置为 pdf 吗?

4

4 回答 4

5

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

Kotlin中的代码示例

private fun getMimeType(file: File) = Tika().detect(file)
于 2018-06-21T08:43:14.150 回答
1

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:

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. 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.

于 2018-01-15T20:23:36.697 回答
0

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

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

于 2015-10-26T10:37:38.847 回答
0

我以前遇到过这个问题,使用以下方法解决了这个问题:

Files.probeContentType(path)

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

于 2021-06-06T14:02:43.720 回答