SpringMvc上传流程

DispatcherServlet

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;

                try {
                    //检查是否是上传文件
                    processedRequest = this.checkMultipart(request);

                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    ...
                    ...

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
        if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
            if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
                if (DispatcherType.REQUEST.equals(request.getDispatcherType())) {
                    this.logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter");
                }
            } else if (this.hasMultipartException(request)) {
                this.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 var3) {
                    if (request.getAttribute("javax.servlet.error.exception") == null) {
                        throw var3;
                    }
                }

                this.logger.debug("Multipart resolution failed for error dispatch", var3);
            }
        }

org.springframework.web.multipart.MultipartHttpServletRequest

 public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
        //走
        return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
    }

org.springframework.web.multipart.support.StandardMultipartHttpServletRequest

public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
        super(request);
        if (!lazyParsing) {
            //这里
            this.parseRequest(request);
        }

    }
private void parseRequest(HttpServletRequest request) {
        try {
            //走这里
            Collection<Part> parts = request.getParts();
            this.multipartParameterNames = new LinkedHashSet(parts.size());
            //形成MultipartFile,供后续mvc解析使用
            MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap(parts.size());
            Iterator var4 = parts.iterator();

            while(var4.hasNext()) {
                Part part = (Part)var4.next();
                String headerValue = part.getHeader("Content-Disposition");
                ContentDisposition disposition = ContentDisposition.parse(headerValue);
                String filename = disposition.getFilename();
                if (filename != null) {
                    if (filename.startsWith("=?") && filename.endsWith("?=")) {
                        filename = StandardMultipartHttpServletRequest.MimeDelegate.decode(filename);
                    }

                    files.add(part.getName(), new StandardMultipartHttpServletRequest.StandardMultipartFile(part, filename));
                } else {
                    this.multipartParameterNames.add(part.getName());
                }
            }

            this.setMultipartFiles(files);
        } catch (Throwable var9) {
            this.handleParseFailure(var9);
        }

    }

org.apache.catalina.connector.RequestFacade

public Collection<Part> getParts() throws IllegalStateException, IOException, ServletException {
        return this.request.getParts();
    }

org.apache.catalina.connector.Request

public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
        //这里
        this.parseParts(true);
        if (this.partsParseException != null) {
            if (this.partsParseException instanceof IOException) {
                throw (IOException)this.partsParseException;
            }

            if (this.partsParseException instanceof IllegalStateException) {
                throw (IllegalStateException)this.partsParseException;
            }

            if (this.partsParseException instanceof ServletException) {
                throw (ServletException)this.partsParseException;
            }
        }

        return this.parts;
    }
 private void parseParts(boolean explicit) {
        if (this.parts == null && this.partsParseException == null) {
                ...
                //这里判断了location的位置默认在context.getServletContext().getAttribute("javax.servlet.context.tempdir")
                ...
                try {
                    //这里
                    List<FileItem> items = upload.parseRequest(new ServletRequestContext(this));

                    int maxPostSize = this.getConnector().getMaxPostSize();
                    int postSize = 0;
                    Charset charset = this.getCharset();
                    Iterator var14 = items.iterator();
                ...
                ...

org.apache.tomcat.util.http.fileupload.FileUploadBase

public List<FileItem> parseRequest(RequestContext ctx) throws FileUploadException {
        List<FileItem> items = new ArrayList();
        boolean successful = false;
        boolean var22 = false;

        FileItem fileItem;
        ArrayList var30;
        try {
            var22 = true;
            FileItemIterator iter = this.getItemIterator(ctx);
            FileItemFactory fileItemFactory = (FileItemFactory)Objects.requireNonNull(this.getFileItemFactory(), "No FileItemFactory has been set.");
            // copy流长度
            byte[] buffer = new byte[8192];

            while(true) {
                if (!iter.hasNext()) {
                    successful = true;
                    var30 = items;
                    var22 = false;
                    break;
                }

                FileItemStream item = iter.next();
                String fileName = item.getName();
                fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName);
                items.add(fileItem);

                try {
                    //输入流转化成临时文件
                    //Streams.copy就是普通的流转化
                    //fileItem有location位置,如果是普通的springboot,这个地址可能是:C:\Users\Administrator\AppData\Local\Temp\tomcat.8080.499296100001\work\Tomcat\localhost\ROOT
                    //这句结束后会生成一个临时文件,可能会叫:upload_f9ee333a_15fd_4136_ba5b_77093199a6c4_00000022.tmp
                    //MultipartFile.transferTo方法会将该文件给删了。

                    //此处流大有管道之意。
                    Streams.copy(item.openStream(), fileItem.getOutputStream(), true, buffer);
                } catch (FileUploadIOException var25) {
                    throw (FileUploadException)var25.getCause();
                } catch (IOException var26) {
                    throw new IOFileUploadException(String.format("Processing of %s request failed. %s", "multipart/form-data", var26.getMessage()), var26);
                }

                FileItemHeaders fih = item.getHeaders();
                fileItem.setHeaders(fih);
            }
            ...
            ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值