关于文件上传

SpringMvc提供了文件上传下载功能

需要依赖第三方包comms-fileupdown

配置

        

接下来我们了解一下文件上传到达处理的Controller时做的预处理。

在请求到达DispatcherServelet时,对文件上传处理的操作是在doDispatch方法中,用于判断这个请求是否是文件上传操作,具体的文件上传相关的操作都在这个方法中实现了。

processedRequest = checkMultipart(request);  
    protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {  
            //首先判断请求是否是文件上传  
            if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {  
                if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {  
                    logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +  
                            "this typically results from an additional MultipartFilter in web.xml");  
                }  
                else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {  
                    logger.debug("Multipart resolution failed for current request before - " +  
                            "skipping re-resolution for undisturbed error rendering");  
                }  
                else {  
                    return this.multipartResolver.resolveMultipart(request);  
                }  
            }  
            //如果不是文件上传则直接返回请求  
            // If not returned before: return original request.  
            return request;  
        }  

this.multipartResolver.isMultipart(request)这个方法操作用来判断请求是否是文件上传操作,具体实现是在我们配置的multipartResolver中

    @Override  
        public boolean isMultipart(HttpServletRequest request) {  
            return (request != null && ServletFileUpload.isMultipartContent(request));  
        }  
ServletFileUpload.isMultipart方法判断请求是否是文件上传的实现是在commons-fileupload包中了,这就是我们为什么需要引入commons-fileupload的原因

当我们已经判断请求是文件上传的请求时,接下来的操作是在this.multipartResolver.resolveMultipart(request);中了。

CommonsMultipartResolver类中的resolveMultipart方法

    @Override  
        public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {  
            Assert.notNull(request, "Request must not be null");  
            //this.resolveLazily默认值是false  
            if (this.resolveLazily) {  
                return new DefaultMultipartHttpServletRequest(request) {  
                    @Override  
                    protected void initializeMultipart() {  
                        MultipartParsingResult parsingResult = parseRequest(request);  
                        setMultipartFiles(parsingResult.getMultipartFiles());  
                        setMultipartParameters(parsingResult.getMultipartParameters());  
                        setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());  
                    }  
                };  
            }  
            else {  
                MultipartParsingResult parsingResult = parseRequest(request);  
                return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),  
                        parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());  
            }  
        }  

具体的解析过程我们就不分析了,最终结果是生成一个DefaultMultipartHttpServletRequest,其主要的实现就是将我们在前端页面上传的文件file,生成MultipartFile对象,这就是为什么在Controller中,我们file参数的类型是MultipartFile,如下,这样我们就可以通过MultipartFile来进行编程来实现文件的一系列操作了。


    public String upload(@RequestParam(value = "file", required = false)MultipartFile... files ){  
              
            for (MultipartFile f : files) {  
                if (f.getSize() > 0) {  
                    File targetFile = new File("1.jpg");  
                    try {  
                        f.transferTo(targetFile);  
                    } catch (IllegalStateException | IOException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
              
            return null;  
        }  
doDispatcher还有一个就是文件上传后的清理动作

你可能感兴趣的:(springMVC)