简体   繁体   English

Spring文件上传内容类型验证,总是八位字节流?

[英]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.

相关问题 无法在Spring / Postman中上传多部分文件和dto对象内容类型&#39;application / octet-stream&#39;不支持 - Unable to upload multipart file and dto object in Spring/Postman Content type 'application/octet-stream' not supported 使用 restTemplate 下载内容类型八位字节流的文件 - Download file of content-type octet-stream using restTemplate application/octet-stream 用于文件上传 - application/octet-stream for file Upload 为什么我的控制器发送内容类型为“ application / octet-stream”? - Why is my controller sending the content type “application/octet-stream”? HTTPUrlConnection和应用程序/八位字节流内容类型响应处理 - HTTPUrlConnection and application/octet-stream content-type response handling 找不到内容类型为application / octet-stream的MessageBodyReader - Unable to find a MessageBodyReader of content-type application/octet-stream Spring WebClient 不将应用程序/八位字节流解码为文件 object - Spring WebClient does not decode application/octet-stream into File object 使用rest服务将zip文件作为八位字节流内容类型上传时,zip文件的大小会受到影响 - Zip file size getting compromise while uploading zip file as octet-stream content type using rest service 为什么除非我将文件命名为 .html,否则上传到 S3 的文件的内容类型为 application/octet-stream? - Why does file uploaded to S3 have content type application/octet-stream unless I name the file .html? 为什么MimetypesFileTypeMap总是为PNG文件返回“application / octet-stream”? - Why does MimetypesFileTypeMap always return “application/octet-stream” for PNG file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM