Spring MVC 和Apache Commons FileUpload基础教程

传统API

示例是基于Spring MVC,Apache Commons FileUpload组件版本是1.3.2。

package com.ice.controller;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class BaseController {
    private HttpServletRequest httpServletRequest;
    private HttpServletResponse httpServletResponse;
    private HttpSession httpSession;

    public HttpServletRequest getHttpServletRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getRequest();
    }

    public HttpServletResponse getHttpServletResponse() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getResponse();
    }

    public HttpSession getHttpSession() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getRequest().getSession();
    }
}

 

package com.ice.controller;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

@Controller
@RequestMapping("/test")
public class TestController extends BaseController {

    @RequestMapping("/test1")
    public String test1() {
        return "test1";
    }

    @RequestMapping("/test2")
    public void test2() throws Exception {
        HttpServletRequest httpServletRequest = getHttpServletRequest();
        HttpServletResponse httpServletResponse = getHttpServletResponse();
        final HttpSession httpSession = httpServletRequest.getSession();

        //过程监听器
        ProgressListener progressListener = new ProgressListener() {
            /**
             * @param pBytesRead 已经读取的字节数
             * @param pContentLength 总字节数
             * @param pItems 字段编号
             */
            public void update(long pBytesRead, long pContentLength, int pItems) {
                httpSession.setAttribute("pBytesRead", pBytesRead);
                httpSession.setAttribute("pContentLength", pContentLength);
                httpSession.setAttribute("pItems", pItems);
            }
        };

        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
        //设置尺寸阈值,单位字节,超过设定值则文件临时写入磁盘,否则保存在内存
        diskFileItemFactory.setSizeThreshold(1024 * 1024);
        //设置文件写入磁盘时临时保存的目录
        diskFileItemFactory.setRepository(new File("d:/"));

        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
        //设置允许上传的单个文件最大尺寸,单位字节,-1代表不限制,参数类型是long
        servletFileUpload.setFileSizeMax(1024 * 1024 * 10l);
        //设置整个请求的大小的最大值,单位字节,-1代表不限制,参数类型是long
        servletFileUpload.setSizeMax(1024 * 1024 * 100l);
        //设置过程监听器
        servletFileUpload.setProgressListener(progressListener);

        boolean isMultipartContent = servletFileUpload.isMultipartContent(httpServletRequest);
        if (isMultipartContent) {
            //开始上传文件并解析请求,按顺序获取各个表单项
            List<FileItem> fileItems = servletFileUpload.parseRequest(httpServletRequest);
            Iterator<FileItem> fileItemIterator = fileItems.iterator();
            while (fileItemIterator.hasNext()) {
                FileItem fileItem = fileItemIterator.next();
                //如果当前表单项是字段
                if (fileItem.isFormField()) {
                    String fieldName = fileItem.getFieldName();//获取字段名
                    String value = fileItem.getString("UTF-8");//获取字段值
                    System.out.println("请求字段:" + fieldName + "=" + value);
                }
                //如果当前表单项是文件
                else {
                    DiskFileItem diskFileItem = (DiskFileItem) fileItem;
                    String fieldName = diskFileItem.getFieldName();//获取字段名
                    String fileName = diskFileItem.getName();//获取浏览器提供的原始文件名
                    String contentType = diskFileItem.getContentType();//获取文件MIME类型
                    long sizeInBytes = diskFileItem.getSize();//获取文件大小,单位字节
                    boolean isInMemory = diskFileItem.isInMemory();//判断文件是否存储在内存中
                    File storeLocation = diskFileItem.getStoreLocation();
                    System.out.println("请求字段:" + fieldName);
                    System.out.println("原始文件名:" + fileName);
                    System.out.println("MIME类型:" + contentType);
                    System.out.println("文件大小(字节):" + sizeInBytes);
                    System.out.println("文件临时保存在内存中?:" + isInMemory);
                    System.out.println("文件临时保存的路径:" + storeLocation.getAbsolutePath());
                    try (InputStream inputStream = diskFileItem.getInputStream()) {
                        FileUtils.copyInputStreamToFile(inputStream, new File("d:/" + fileName));
                    }
                    //删除临时文件
                    diskFileItem.delete();
                }
            }
        }

        try (PrintWriter printWriter = httpServletResponse.getWriter()) {
            httpServletResponse.setContentType("text/html; charset=utf-8");
            printWriter.println("<script>alert('上传成功');</script>");
        }
    }
}

 

请求头:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:755
Content-Type:multipart/form-data; boundary=-----------------------------65982022822840
Cookie:JSESSIONID=wg5h37bt3rcr1dcpes14s42jz
Host:localhost:9443
Origin:https://localhost:9443
Referer:https://localhost:9443/ice-web1/test/test1
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36

请求有效负荷
-----------------------------65982022822840
Content-Disposition: form-data; name="userName"

匿名
-----------------------------65982022822840
Content-Disposition: form-data; name="userAge"

20
-----------------------------65982022822840
Content-Disposition: form-data; name="uploadFile"; filename="测试文件"
Content-Type: application/octet-stream
这里隐藏文件具体内容
-----------------------------65982022822840--

 

 

 

流式API

和传统API不一样的是,传统API中文件在被用户读取前,必须等待被保存在内存或者硬盘中(临时文件),这种方法非常简单,但是另一方面却带来了内存和时间上的额外开销。流式API更佳轻量级,它可以让你牺牲一点便利性以换得理想的性能,文件可以直接从网络输入流中获取。

    @RequestMapping("/test3")
    public void test3() throws Exception {
        HttpServletRequest httpServletRequest = getHttpServletRequest();
        HttpServletResponse httpServletResponse = getHttpServletResponse();

        //过程监听器
        ProgressListener progressListener = new ProgressListener() {
            /**
             * @param pBytesRead 已经读取的字节数
             * @param pContentLength 总字节数
             * @param pItems 字段编号
             */
            public void update(long pBytesRead, long pContentLength, int pItems) {
                System.out.println("已读取字节:" + pBytesRead);
                System.out.println("总字节:" + pContentLength);
                System.out.println("字段编号:" + pItems);
            }
        };

        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();

        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
        //设置允许上传的单个文件最大尺寸,单位字节
        servletFileUpload.setFileSizeMax(1024 * 1024 * 1024 * 10l);
        //设置整个请求的大小的最大值,单位字节
        servletFileUpload.setSizeMax(1024 * 1024 * 1024 * 100l);
        //设置过程监听器
        servletFileUpload.setProgressListener(progressListener);

        boolean isMultipartContent = servletFileUpload.isMultipartContent(httpServletRequest);
        if (isMultipartContent) {
            //开始上传文件并解析请求,按顺序获取各个表单项
            FileItemIterator fileItemIterator = servletFileUpload.getItemIterator(httpServletRequest);
            while (fileItemIterator.hasNext()) {
                FileItemStream fileItemStream = fileItemIterator.next();
                String name = fileItemStream.getFieldName();
                if (fileItemStream.isFormField()) {
                    try (InputStream inputStream = fileItemStream.openStream()) {
                        System.out.println("表单字段:" + name + ",值:"
                                + Streams.asString(inputStream, "utf-8"));
                    }
                } else {
                    System.out.println("原始文件名:" + fileItemStream.getName());
                    System.out.println("MIME类型:" + fileItemStream.getContentType());
                    try (
                            //文件输出流
                            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:/" + fileItemStream.getName()));
                            //文件输入流
                            InputStream inputStream = new BufferedInputStream(fileItemStream.openStream());) {
                        byte[] bytes = new byte[1024 * 8];
                        int n;
                        while (-1 != (n = inputStream.read(bytes))) {
                            bufferedOutputStream.write(bytes, 0, n);
                        }
                    }
                }
            }
        }

        try (PrintWriter printWriter = httpServletResponse.getWriter()) {
            httpServletResponse.setContentType("text/html; charset=utf-8");
            printWriter.println("<script>alert('上传成功');</script>");
        }
    }

 

 

转自:http://blog.youkuaiyun.com/gjb724332682/article/details/70148915

 

转载于:https://my.oschina.net/lenglingx/blog/1580307

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值