简体   繁体   English

Spring Boot分段上传获取空文件对象

[英]Spring Boot multipart upload getting null file object

I am getting a problem while implementing multipart file upload using spring boot 1.5.2. 使用spring boot 1.5.2实现多部分文件上载时遇到问题。

Here is the situation, I have a mapping to handle file upload process.While I start the spring server, it starts without any error. 这是情况,我有一个映射来处理文件上传过程。当我启动spring服务器时,它启动没有任何错误。 The problem is that I would either able to upload the file perfectly fine or I would get null on all attribute in FileBucket object . 问题是我要么能够完全上传文件,要么在FileBucket对象中的所有属性上都为null

This situation would stay forever if I do not shutdown the server. 如果我不关闭服务器,这种情况将永远存在。

  • If it could upload, it would upload fine for the rest of the time. 如果它可以上传,它将在其余时间上传罚款。
  • If not, it won't work until I restart the server(likely more than one time) 如果没有,它将无法工作,直到我重新启动服务器(可能不止一次)

Here is the mapping. 这是映射。

@RequestMapping(value = {"/api/upload"}, method = RequestMethod.POST)
public ResponseEntity<Map<String, Integer>> upload(@Valid FileBucket fileBucket, BindingResult result) throws IOException {
        Session session = sessionFactory.openSession();
        User user = (User) session.load(User.class, getUserId());

        Map<String, Integer> model = new HashMap<String, Integer>();
        if (result.hasErrors()) {
            System.out.println("validation errors");
            System.out.println(result);
            session.close();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        } else {
            int documentId = saveDocument(fileBucket, user);
            model.put("documentId", documentId);
            session.close();
            return new ResponseEntity<Map<String, Integer>>(model, HttpStatus.OK);
        }
}

And the FileBucket object FileBucket对象

public class FileBucketConversation {

    private MultipartFile file;

    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }
}

I have tried few ways to implement file upload, and still having the same situation. 我已经尝试了几种方法来实现文件上传,并且仍然具有相同的情况。

  1. Using StandardServletMultipartResolver . 使用StandardServletMultipartResolver

     @Bean(name = "multipartResolver") public StandardServletMultipartResolver resolver() { return new StandardServletMultipartResolver(); } 
  2. Using CommonsMultipartResolver v1.3.2. 使用CommonsMultipartResolver v1.3.2。

     @Bean(name="multipartResolver") public CommonsMultipartResolver multipartResolver () { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(MAX_FILE_SIZE); return resolver; } 

    overriding MultipartFilter 重写MultipartFilter

     @Bean @Order(0) public MultipartFilter multipartFile() { MultipartFilter multipartFilter = new MultipartFilter(); multipartFilter.setMultipartResolverBeanName("multipartResolver"); return multipartFilter; } 
  3. Enable spring.http.multipart in properties file 在属性文件中启用spring.http.multipart

     spring.http.multipart.enabled=true spring.http.multipart.max-file-size=20Mb spring.http.multipart.max-request-size=20Mb 

I really have no clue where to start looking. 我真的不知道从哪里开始寻找。 The problem happen occasionally, it do not happen every time I start the server but most of the time. 这个问题偶尔会发生,每次启动服务器时都不会发生,但大部分时间都没有。 Hoping some one could help me. 希望有人可以帮助我。

Thank you. 谢谢。

I had the same problem, this is my solution: 我有同样的问题,这是我的解决方案:

In application.yml: 在application.yml中:

spring:
  http:
    multipart:
      enabled: false

In configuration: 在配置中:

import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
...

@Bean
public MultipartResolver multipartResolver() {
    return new CommonsMultipartResolver();
}

In RestController: 在RestController中:

@PostMapping(value = "api/upload", consumes = "multipart/form-data") 
public void enablePurchase(@RequestHeader HttpHeaders headers,
                           FileBucketConversation fileBucketConversation) {
...
}

Important: In your client don't use any header to define the Content-type or boundary. 重要提示:在您的客户端中,不要使用任何标头来定义内容类型或边界。 I'm using Angular 4 and when I remove these headers from my code it works (I only set the User token): 我正在使用Angular 4,当我从我的代码中删除这些标题时,它可以工作(我只设置用户标记):

/* DON'T USE THIS:
let boundary = "ABDCE";
headers.append("Content-type", "multipart/form-data;boundary=" + boundary);
headers.append("enctype", "multipart/form-data;boundary=" + boundary);
headers.append("boundary", boundary);
*/

I hope this help you. 我希望这对你有帮助。

Update for Spring Boot 2 and Spring 5 Spring Boot 2和Spring 5的更新

spring.http.multipart.enabled is deprecated, so forget about it. 不推荐使用spring.http.multipart.enabled ,所以spring.http.multipart.enabled它。

Registering my own beans for MultipartConfigElement or MultipartResolver broke it for me. MultipartConfigElementMultipartResolver注册我自己的bean打破了它。

I ended up with a @PostMapping method with a single parameter, @RequestPart(name = "file") MultipartFile file . 我最终得到了一个带有单个参数的@PostMapping方法, @PostMapping @RequestPart(name = "file") MultipartFile file Adding a parameter @RequestHeader HttpHeader headers helped me make sure the client was sending the required header Content-Type with a boundary. 添加参数@RequestHeader HttpHeader headers帮助我确保客户端发送带边界的所需标头Content-Type。

I'm using a Node client with the form-data library and node-fetch . 我正在使用带有表单数据库和节点获取的Node客户端。 Here's the client code: 这是客户端代码:

const formData = new FormData();
const fileMetadata = {filename: fileName, contentType: 'image/png', knownLength: fs.statSync(pathToFile)};
const formData.append('file', fs.createReadStream(pathToFile), fileMetadata);
fetch(url, {method: 'POST', body: formData});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM