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

时间:2015-10-26 10:12:01

标签: java spring spring-mvc postman spring-rest

我正在尝试在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?

4 个答案:

答案 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)

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