【问题标题】:File is always null in srpingboot 1.3.7 when processing multipart/form-data request处理多部分/表单数据请求时,Spring Boot 1.3.7 中的文件始终为空
【发布时间】:2020-05-02 02:57:08
【问题描述】:

我正在尝试将 grails 应用程序与 springboot 应用程序通信。我正在尝试将文件上传到之前已上传到 grails 的 springboot 应用程序。 这是我的springboot控制器的代码:

@ResponseBody
    @PostMapping(value = "/save", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    def save(@Valid @ModelAttribute SaveRequest request) {
        //Some logic
}

saveRequest 类包含一些需要应用于请求的验证

class SaveHotelAccreditationRequest {

    //Other fields

    @NotNull
    MultipartFile image

}

我已经像这样在 application.properties 文件中设置了属性

spring.http.multipart.enabled = true
spring.http.multipart.location=/home/user/temp

我正在使用 Apache 的 commons-io 和 commons-fileupload 库。 我已经像这样设置了多部分解析器

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(2*1024*1024);
    return multipartResolver;
}

这是我的 grails 应用程序中的代码

CredentialsProvider credsProvider = new BasicCredentialsProvider()
    credsProvider.setCredentials(
            AuthScope.ANY,
            new UsernamePasswordCredentials(userName, password))
    CloseableHttpClient httpclient = HttpClients.custom()
            .setDefaultCredentialsProvider(credsProvider)
            .build()
    try {
        HttpPost httpPost = new HttpPost(url)
        MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create()
        reqEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
        reqEntity.addBinaryBody('image', file, ContentType.MULTIPART_FORM_DATA, file.getName())
        //Other fields
        httpPost.setEntity(reqEntity.build())
        System.out.println("Executing request " + httpPost.getRequestLine())
        CloseableHttpResponse response = httpclient.execute(httpPost)
        try {
            System.out.println("----------------------------------------")
            System.out.println(response.getStatusLine())
            System.out.println(EntityUtils.toString(response.getEntity()))
        } finally {
            response.close()
        }
    } finally {
        httpclient.close()
    }

当我运行请求时,我收到以下错误消息:

2020-05-02 02:37:24 | WARN | org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved
 exception caused by Handler execution: org.springframework.validation.BindException: org.springframework.validatio
n.BeanPropertyBindingResult: 1 errors
Field error in object 'saveHotelAccreditationRequest' on field 'image': rejected value [null]; codes [NotNull.saveRequest.image,NotNull.image,NotNull.org.springframework.web.multipart.MultipartFile,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [saveRequest.image,image]; arguments []; default message [image]]; default message [may not be null]

我尝试过使用邮递员,但我收到了相同的错误消息。我无法弄清楚我在这里缺少什么,任何帮助将不胜感激。

【问题讨论】:

    标签: java spring-boot rest grails groovy


    【解决方案1】:

    在用于多部分 API 的 Spring-Boot REST 中,我正在编写这样的多部分 API

    @PostMapping("/upload-doc")
    @ApiImplicitParam(paramType = "body", name = "payload", dataType = "UploadDocRequest")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiOperation("Upload User's documents")
    public UploadDocRequest uploadDocRequest(
            @RequestPart("payload") UploadDocRequest payload, @RequestPart("docs") MultipartFile[] docs) {
    

    yaml 中的 Spring Multipart 配置

    spring:
     servlet:
      multipart:
       max-file-size: 5MB
       max-request-size: 5MB
    

    以及如何从 PostMan 调用它-

    【讨论】:

      【解决方案2】:

      在使用 Multipart 时,以下内容在 Spring boot 中对我有用。

      @PostMapping(value = "/uploadVideo")
      public void uploadVideo(HttpServletRequest request, HttpServletResponse response,
                  @RequestParam("file") MultipartFile file) throws Exception {
          // logic here
      }
      

      您用于最大尺寸的多部分解析器可以像这样在属性文件中配置

      # Max file size.
      spring.servlet.multipart.max-file-size=200MB
      # Max Request Size
      spring.servlet.multipart.max-request-size=215MB
      

      我是这样从 Angular App 调用的

      var reqHeader=new HttpHeaders();
          reqHeader.append('contentType','multipart/form-data')
          let options = { headers: reqHeader, params: new HttpParams()
                                
                         };
          const formData = new FormData();
          formData.append('file', file )
          return this.http.post(this.url_toreadFile,formData,options)
      

      希望它可以为您的实施提供一些帮助。

      【讨论】:

        猜你喜欢
        • 2020-03-14
        • 2018-07-02
        • 2014-09-21
        • 1970-01-01
        • 2013-04-27
        • 1970-01-01
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        相关资源
        最近更新 更多