环境:

SpringMVC项目搭建

文件上传

1、加入相关依赖

2、配置multipartResolver

在springMVC.xml中加入multipartResolver相关配置:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="utf-8" />
    <property name="maxUploadSize" value="10485760000" />
    <property name="maxInMemorySize" value="40960"  />  
</bean>  

3、实现action

package com.celloud.action;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/files")
public class FilesAction {
    private static String upload_path = "/Users/sun8wd/Documents/testUpload";

    @RequestMapping("/upload1")
    public ModelAndView upload1(@RequestParam("file") CommonsMultipartFile[] files, HttpServletRequest request) {
        long time = System.currentTimeMillis();
        for (int i = 0; i < files.length; i++) {
            System.out.println("fileName---------->" + files[i].getOriginalFilename());
            if (files[i].isEmpty()) {
                continue;
            }
            try {
                File file = new File(upload_path + File.separatorChar+ files[i].getOriginalFilename());
                System.out.println(file.getAbsolutePath());
                OutputStream outputStream = new FileOutputStream(file);
                InputStream inputStream = files[i].getInputStream();
                byte[] temp = new byte[1024 * 1024];
                int length = 0;
                while ((length = inputStream.read(temp)) > 0) {
                    outputStream.write(temp, 0, length);
                }
                outputStream.flush();
                outputStream.close();
                inputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(System.currentTimeMillis()-time);
        // 相同5个文件,执行多次,每次执行时间在80-90毫秒之间
        return listFiles();
    }
    @RequestMapping("/upload2")
    public ModelAndView upload2(HttpServletRequest request, HttpServletResponse response) {
        // 创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        // 判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            // 记录上传过程起始时的时间,用来计算上传时间
            long time = System.currentTimeMillis();
            // 转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                // 取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    // 取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    // 如果名称不为“”,说明该文件存在,否则说明该文件不存在
                    if (!"".equals(myFileName.trim()) ) {
                        System.out.println(myFileName);
                        // 重命名上传后的文件名
                        String fileName = upload_path + File.separatorChar + file.getOriginalFilename();
                        // 定义上传路径
                        File localFile = new File(fileName);
                        try {
                            file.transferTo(localFile);
                        } catch (IllegalStateException | IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                // 记录上传该文件后的时间

            }
            System.out.println(System.currentTimeMillis()-time);
            // 相同5个文件,执行多次,每次执行时间在1-6毫秒之间
        }
        return listFiles();
    }
    public ModelAndView listFiles(){
        ModelAndView mv = new ModelAndView("upload/listfiles");
        File file = new File(upload_path);
        String[] files = file.list();
        mv.addObject("files",files);
        return mv;
    }
}

4、实现jsp

upload.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>upload</title>
</head>
<body>
    <div style="background-color: #f9f6f4; border: 2px solid red;">
        <form action="/springMVC-demo/files/upload1"
            enctype="multipart/form-data" method="post">
            <h3>upload1</h3>
            <input type="file" name="file">
            <br />
            <input type="file" name="file">
            <br />
            <input type="file" name="file">
            <br />
            <input type="file" name="file">
            <br />
            <input type="file" name="file">
            <br />
            <br />
            <input type="submit" value="上传" />
        </form>
    </div>
    <br />
    <br />
    <div style="background-color: #e3e3e3; border: 2px solid red">
        <h3>upload2</h3>
        <form action="/springMVC-demo/files/upload2"
            enctype="multipart/form-data" method="post">
            <input type="file" name="file_1">
            <br />
            <input type="file" name="file_2">
            <br />
            <input type="file" name="file_3">
            <br />
            <input type="file" name="file_4">
            <br />
            <input type="file" name="file_5">
            <br />
            <br />
            <input type="submit" value="上传" />
        </form>
    </div>
</body>
</html>

listfiles.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>listfiles</title>
</head>
<body>
    <table>
        <tr>
            <th>文件名</th>
            <th>下载</th>
        </tr>
        <c:forEach items="${files }" var="file">
            <tr>
                <td>${file }</td>
                <td><a href="#">下载</a></td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

5、验证

upload1和upload2分别上传5个相同文件,并多次执行,upload1执行时间在80-90毫秒,upooad2执行时间在1-10毫秒

原因应该在于upload1中的输入输出流效率要低于upload2中的file.transferTo(localFile);

文件下载

1、修改jsp

在listfiles.jsp中,修改下载链接的地址,为:

/springMVC-demo/files/download?filename=${file}"

2、实现action

在FilesAction中,加入文件下载的方法:

@RequestMapping("/download")
public ResponseEntity<byte[]> download(String filename) throws Exception {
    System.out.println(filename);
    File file = new File(upload_path + File.separatorChar + filename);
    HttpHeaders headers = new HttpHeaders();
    String fileName = new String(filename.getBytes("UTF-8"), "iso-8859-1");// 为了解决中文名称乱码问题
    headers.setContentDispositionFormData("attachment", fileName);
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}

3、验证

访问http://localhost:8080/springMVC-demo/files/listfiles

点击页面中的下载