本文将说明spring上传文件如何配置,以及从request请求中解析到文件流的原理
#添加依赖
主要用来解析request请求流,获取文件字段名、上传文件名、content-type、headers等内容组装成FileItem
<!--添加fileupload依赖--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
#构建单例bean
CommonsMultipartResolver,将request请求从类型HttpServletRequest转化成MultipartHttpServletRequest,从MultipartHttpServletRequest可以获取上传文件的各种信息文件名、文件流等内容
注意:该bean的beanName要写成multipartResolver,否则无法获取到该bean
@Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); // 上传限制最大字节数 -1表示没限制 commonsMultipartResolver.setMaxUploadSize(-1); // 每个文件限制最大字节数 -1表示没限制 commonsMultipartResolver.setMaxUploadSizePerFile(-1); commonsMultipartResolver.setDefaultEncoding(StandardCharsets.UTF_8.name()); return commonsMultipartResolver; } #DispatcherServlet public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; private void initMultipartResolver(ApplicationContext context) { try { this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using MultipartResolver [" + this.multipartResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // Default is no multipart resolver. this.multipartResolver = null; if (logger.isDebugEnabled()) { logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME + "': no multipart request handling provided"); } } }
~~java思维导图获取路径~~
#校验请求
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException { // multipartResolver不为空 且 request请求头中的content-type以multipart/开头 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 (hasMultipartException(request)) { logger.debug("Multipart resolution previously failed for current request - " + "skipping re-resolution for undisturbed error rendering"); } else { try { // 解析请求 return this.multipartResolver.resolveMultipart(request); } catch (MultipartException ex) { if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) { logger.debug("Multipart resolution failed for error dispatch", ex); // Keep processing error dispatch with regular request handle below } else { throw ex; } } } } // If not returned before: return original request. return request; }
#解析请求
@Override public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException { Assert.notNull(request, "Request must not be null"); MultipartParsingResult parsingResult = parseRequest(request); return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes()); } protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { String encoding = determineEncoding(request); // 获取FileUpload实例 FileUpload fileUpload = prepareFileUpload(encoding); try { // 将request请求解析成FileItem List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadBase.FileSizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); } catch (FileUploadException ex) { throw new MultipartException("Failed to parse multipart servlet request", ex); } } // ctx->将request进行了包装 public List<FileItem> parseRequest(RequestContext ctx) throws FileUploadException { List<FileItem> items = new ArrayList<FileItem>(