Front-end AsyncHttpClient, back-end SpringMvc batch upload file solution

AsyncHttpClient + SpringMvc upload files in batches, and the parameter names of the files received by the backend are the same. The backend of the

latest project uses SpringMvc, and the backend code is as follows:
	//Use pic to receive multiple files
	@RequestMapping("/upload.dhtml")
	@ResponseBody
	public String test3(CommonsMultipartFile[] pic) {
		// do upload
		return "success";
	}

The Android front-end uses AsyncHttpClient, and it is found that the batch upload problem cannot be realized. The problem is as follows.

1. After Android reads the file, it compresses it into InputStream, and finally gets List<InputStream>
List<File> files = ...;
List<InputStream> streams = 压缩(files);


2. There are 2 methods for uploading files provided by AsyncHttpClient
    public void put(String key, InputStream stream) {
        put(key, stream, null);
    }

    public void put(String key, File files[]) throws FileNotFoundException {
        put(key, files, null, null);
    }


3. There is no batch upload method for InputStream. If you use file batch upload, you have to do the following
List<InputStream> streams = ...;
File[] files = create temporary files (streams);
RequestParams params = getRequestParams();
params.put("pic", files);


Such shortcomings are obvious! ! !

So, how to solve it?
1. Inherit RequestParams and implement a method for adding Streams in batches, as follows:
put(String key, List<InputStream> streams);

2. Modify the back-end code to receive multiple files with different keys, such as:
	//Use pic0, pic1, pic2 to receive multiple files
	@RequestMapping("/upload.dhtml")
	@ResponseBody
	public String test3(CommonsMultipartFile pic,CommonsMultipartFile pic1,CommonsMultipartFile pic2) {
		// do upload
		return "success";
	}

3. The backend abandons Spring's automatic assembly, handles the file upload by itself, and ignores the file name
        //Create a generic multipart parser  
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());  
        / / Determine whether the request has a file upload, that is, a multi-part request  
        if(multipartResolver.isMultipart(request)){  
            //Convert to multipart request    
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;  
            //Get all the file names in the request  
            Iterator<String> iter = multiRequest.getFileNames();  
            while(iter.hasNext()){   
                // get the uploaded file  
                MultipartFile file = multiRequest.getFile(iter.next());  
                if(file != null){  
                    // handle file upload and write to disk
                }  
            }  
              
        }  


Analysis:
1. Directly pass the pass, and do not modify the third-party library unless it is absolutely necessary. Consider maintenance and stability
. 2. Although the pass is achievable, the implementation method is too discordant, and the number of front-end batch uploads needs to be limited.
3 , Pass off, the performance of this method is much worse than Spring autowiring.

Solution:
use different keys to represent files when uploading from the front end, such as
		RequestParams params = getRequestParams();
		List<InputStream> streams = ...;
		for(int i=0;i<strams.size();i++){
			params.put("pic["+i+"]",strams.get(i));
		}

Backend code:
//Use picObj to receive multiple files
@RequestMapping("/upload.dhtml")
@ResponseBody
public String test3(Pics picObj) {
	List<CommonsMultipartFile> pic = picObj.getPic();
	for(CommonsMultipartFile file:pic){
		// do upload
	}
	return "success";
}
class Pics{
	private List<CommonsMultipartFile> pic;

	public List<CommonsMultipartFile> getPic() {
		return pic;
	}

	public void setPic(List<CommonsMultipartFile> pic) {
		this.pic = pic;
	}
}


Get it done. .

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327049153&siteId=291194637