简体   繁体   中英

How to get all submitted MultipartFiles, regardless of their name

I would like a user to be able to submit any number of files with arbitrary name and origfilename.

How would one get a list of submitted files in a request?

@RequestParam(name = "*") MultipartFile[] files

I was hoping using regex or similar in name parameter would work, but all my testing failed.

Equivalent in Flask would be

request.files

Any ideas?

Related question: Getting files in controller without @RequestParam name

You can get requested multipart files by using MultipartRequest#getFileMap like this:

MultipartRequest multipartRequest = .....
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
MultipartFile[] files = fileMap.values().toArray(new MultipartFile[0]);
...

Also you can get all the files by using MultipartRequest#getMultiFileMap even when the same parameter name is assigned to multiple files for example:

    <input type="file" name="file1"/>file1
    <input type="file" name="file2"/>file2
    <input type="file" name="file2"/>file2X

Spring's DispatcherServlet / MultipartFilter wraps HttpServletRequest object in MultipartHttpServletRequest (extending MultipartRequest ) object when you send a multipart/form-data with a request and MultipartRequest can be a controller's method argument.
So your controller's method will be something like this:

    @RequestMapping("upload")
    public String upload(MultipartRequest multipartRequest) {

        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        MultipartFile[] files = fileMap.values().toArray(new MultipartFile[0]);

        // Use when the same parameter name is assigned to multiple files.
        // MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
        // MultipartFile[] files = multiFileMap.values().stream().flatMap(values -> values.stream()).toArray(MultipartFile[]::new);

        for (MultipartFile multipartFile : files) {
            System.out.println("param name: " + multipartFile.getName());
            System.out.println("filename: " + multipartFile.getOriginalFilename());
            System.out.println("size: " + multipartFile.getSize());

        }

        return ".....";
    }

When you send '1.jpg'(parameter name is 'file1') and '2.jpg'(parameter name is 'file2'), you get the output like this:

param name: file1
filename: 1.jpg
size: 155152
param name: file2
filename: 2.jpg
size: 154015

[UPDATE]

I have found a more simple solution. Map<String, MultipartFile> / MultiValueMap<String, MultipartFile> can also be a controller's method argument with @RequestParam annotation whose name attribute is empty. Therefore you can simplify the controller's method like this:

@RequestMapping("upload")
public String upload(@RequestParam Map<String, MultipartFile> fileMap) {
    MultipartFile[] files = fileMap.values().toArray(new MultipartFile[0]);
    .......
    return ......
}

or

@RequestMapping("upload")
public String upload(@RequestParam MultiValueMap<String, MultipartFile> multiFileMap) {

    MultipartFile[] files = multiFileMap.values().stream().flatMap(values -> values.stream())
            .toArray(MultipartFile[]::new);
     .......
     return ......
}

See Also

Javadoc of DispatcherServlet#checkMultipart
Javadoc of MultipartFilter
Javadoc of MultipartResolver#resolveMultipart
Javadoc of MultipartHttpServletRequest
Javadoc of RequestParamMapMethodArgumentResolver [UPDATE]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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