SpingMvc实现上传文件的操作

110 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情

文件上传

文件上传要求

Http协议规定了我们在进行文件上传时的请求格式要求。所以在进行文件上传时,除了在表单中增加一个用于上传文件的表单项(input标签,type=file) 外必须要满足以下的条件才能进行上传。

①请求方式为POST请求

如果是使用表单进行提交的话,可以把form标签的method属性设置为POST。例如:

    <form action="/upload" method="post">
​
    </form>

②请求头Content-Type必须为multipart/form-data

如果是使用表单的话可以把表单的entype属性设置成multipart/form-data。例如:

    <form action="/upload" method="post" enctype="multipart/form-data">
​
    </form>

SpringMVC接收上传过来的文件

SpringMVC使用commons-fileupload的包对文件上传进行了封装,我们只需要引入相关依赖和进行相应配置就可以很轻松的实现文件上传的功能。

①依赖

        <!--commons文件上传,如果需要文件上传功能,需要添加本依赖-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

②配置

  <!--
            文件上传解析器
            注意:id 必须为 multipartResolver
        -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置默认字符编码 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 一次请求上传的文件的总大小的最大值,单位是字节-->
        <property name="maxUploadSize" value="#{1024*1024*100}"/>
        <!-- 每个上传文件大小的最大值,单位是字节-->
        <property name="maxUploadSizePerFile" value="#{1024*1024*50}"/>
    </bean>

③接收上传的文件数据并处理

上传表单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="uploadFile">
        <input type="submit">
    </form>
</body>
</html>
@Controller
public class UploadController {
​
    @RequestMapping("/upload")
    public String upload(MultipartFile uploadFile) throws IOException {
        //文件存储 把上传上来的文件存储下来
        uploadFile.transferTo(new File("test.sql"));
        return "/success.jsp";
    }
}

注意:方法参数名要和提交上来的参数名一致。

MultipartFile常见用法

  • 获取上传文件的原名

    uploadFile.getOriginalFilename()
    
  • 获取文件类型的MIME类型

    uploadFile.getContentType()
    
  • 获取上传文件的大小

    uploadFile.getSize()
    
  • 获取对应上传文件的输入流

    uploadFile.getInputStream()
    

文件下载

文件下载要求

如果我们想提供文件下载的功能。HTTP协议要求我们的必须满足如下规则。

①设置响应头Content-Type

要求把提供下载文件的MIME类型作为响应头Content-Type的值

②设置响应头Content-disposition

要求把文件名经过URL编码后的值写入响应头Content-disposition。但是要求符合以下格式,因为这样可以解决不同浏览器中文文件名 乱码问题。

Content-disposition: attachment; 
filename=%E4%B8%8B%E6%B5%B7%E5%81%9Aup%E4%B8%BB%E9%82%A3%E4%BA%9B%E5%B9%B4.txt;
filename*=utf-8''%E4%B8%8B%E6%B5%B7%E5%81%9Aup%E4%B8%BB%E9%82%A3%E4%BA%9B%E5%B9%B4.txt

③文件数据写入响应体中

代码实现

我们可以使用之前封装的下载工具类实现文件下载

工具类代码:

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
​
public class DownLoadUtils {
    /**
     * 该方法可以快速实现设置两个下载需要的响应头和把文件数据写入响应体
     * @param filePath 该文件的相对路径
     * @param context  ServletContext对象
     * @param response
     * @throws Exception
     */
    public static void downloadFile(String filePath, ServletContext context, HttpServletResponse response) throws Exception {
        String realPath = context.getRealPath(filePath);
        File file = new File(realPath);
        String filename = file.getName();
        FileInputStream fis = new FileInputStream(realPath);
        String mimeType = context.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);
        String fname= URLEncoder.encode(filename,"UTF-8");
        response.setHeader("Content-disposition","attachment; filename="+fname+";"+"filename*=utf-8''"+fname);
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024 * 8];
        int len = 0;
        while((len = fis.read(buff)) != -1){
            sos.write(buff,0,len);
        }
        sos.close();
        fis.close();
    }
}
​

Handler方法定义

@Controller
public class DownLoadController {
​
    @RequestMapping("/download")
    public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //文件下载
        DownLoadUtils.downloadFile("/WEB-INF/file/下海做UP主那些年.txt",request.getServletContext(),response);
    }
}