SpringMVC教程之文件上传与下载详解

下面我会为大家详细讲解“SpringMVC教程之文件上传与下载详解”的完整攻略。

下面我会为大家详细讲解“SpringMVC教程之文件上传与下载详解”的完整攻略。

一、背景

在 web 开发中,文件的上传和下载是非常常见的操作。Spring 框架提供了相应的类和接口,可以方便地实现文件上传和下载功能。本文将结合两个实例,介绍 SpringMVC 的文件上传和下载的实现方法。

二、文件上传

2.1 概述

文件上传分为两步:

  1. 在表单中添加文件上传控件,用于选择要上传的文件。

  2. 服务器端处理文件上传请求,将文件保存到指定的位置。

2.2 简单示例

上传文件的示例代码如下。首先是前端的表单界面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传示例</title>
</head>
<body>
    <form method="post" action="/upload" enctype="multipart/form-data">
        <input type="file" name="file" />
        <input type="submit" value="上传" />
    </form>
</body>
</html>

其中,<form> 标签中的 method 属性必须指定为 postaction 属性对应的是文件上传请求的处理地址。

服务器端对于文件上传请求的处理,示例代码如下:

@Controller
public class FileUploadController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String upload(@RequestParam("file") MultipartFile file, Model model) throws IOException {
        if (!file.isEmpty()) {
            byte[] bytes = file.getBytes();
            FileOutputStream fos = new FileOutputStream("C:/temp/" + file.getOriginalFilename());
            fos.write(bytes);
            fos.close();
            model.addAttribute("msg", "文件上传成功!");
        } else {
            model.addAttribute("msg", "文件上传失败:文件为空!");
        }
        return "uploadResult";
    }

}

该类使用 @Controller 注解声明为控制器, @RequestMapping 注解指定处理 "/upload" 请求,其中 @RequestParam("file") 注解指定上传文件的参数名为 file。在方法体中,使用 getBytes() 方法获取文件的字节流,保存到指定的文件中。最后,通过 model 传递消息给视图,告知上传结果。其中名为 uploadResult 的视图用于展示上传结果。

至此,简单的文件上传功能已经实现了。若出现错误,报错信息将会在视图 uploadResult 中显示出来。

2.3 进阶示例

进阶的文件上传示例实现了以下几个特性:

  1. 使用 Spring 的表单标签库,生成包含文件上传功能的表单界面。

  2. 实现同时上传多个文件的功能。

  3. 限制上传文件的类型和大小。

先来看看前端的表单界面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传示例</title>
</head>
<body>
    <%@ taglib uri="http://www.springframework.org/tags/form" prefix="f" %>
    <f:form method="post" action="/simpleUpload" commandName="myFile">
        <f:input type="file" path="files" id="files" name="files" multiple="multiple" /><br />
        <f:errors path="files" cssClass="error" />
        <br />
        <input type="submit" value="上传" />
    </f:form>
</body>
</html>

在该表单界面中使用了 Spring 的表单标签库,通过 f:form 标签生成 form 表单,commandName 属性指定表单的 model 类,后续会用到。在表单中使用 f:input 标签生成文件上传控件,通过 path 属性指定上传文件的属性名(即使用 setter 方法设置这个参数)。

然后,我们需要在后端实现文件上传功能。示例代码如下:

@Controller
public class AdvancedFileUploadController {

    @RequestMapping(value = "/simpleUpload", method = RequestMethod.POST)
    public String simpleUpload(@ModelAttribute("myFile") MyFile myFile, BindingResult result, Model model)
            throws IOException {
        if (result.hasErrors()) {
            model.addAttribute("msg", "上传失败:表单验证出错!");
            return "advancedUploadResult";
        }
        List<MultipartFile> files = myFile.getFiles();
        if (files.size() == 0) {
            model.addAttribute("msg", "上传失败:未选择任何文件!");
            return "advancedUploadResult";
        }
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                String fileName = file.getOriginalFilename();
                String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
                if (!fileType.equalsIgnoreCase("jpg") && !fileType.equalsIgnoreCase("png")) {
                    model.addAttribute("msg", "上传失败:文件类型不正确!");
                    return "advancedUploadResult";
                }
                if (file.getSize() > 1024 * 1024) {
                    model.addAttribute("msg", "上传失败:文件大小超限!");
                    return "advancedUploadResult";
                }
                byte[] bytes = file.getBytes();
                FileOutputStream fos = new FileOutputStream("C:/temp/" + fileName);
                fos.write(bytes);
                fos.close();
            }
        }
        model.addAttribute("msg", "上传成功!");
        return "advancedUploadResult";
    }

    @RequestMapping(value = "/advancedUpload", method = RequestMethod.GET)
    public String showUploadForm(Model model) {
        model.addAttribute("myFile", new MyFile());
        return "advancedUpload";
    }

}

class MyFile {
    private List<MultipartFile> files;

    public List<MultipartFile> getFiles() {
        return files;
    }

    public void setFiles(List<MultipartFile> files) {
        this.files = files;
    }

}

其中 @ModelAttribute("myFile") 注解指定 model 的名称为 myFile,在表单中就可以使用 myFile.files 的方式获取上传文件列表。使用 BindingResult 对上传的数据进行校验,若校验失败,将错误信息展示在视图中。调用 getFiles() 方法按顺序获取到上传文件列表,遍历其中文件:

在遍历的过程中,首先获取文件名,并从文件名中获取文件类型。然后判断文件类型和大小是否符合要求,不符合则返回错误消息。最后,使用 getBytes() 方法获取文件的字节流,保存到指定的文件中。

在实现文件上传功能中,我们还可以结合第三方组件 commons-fileupload 来解析上传文件流。在 Spring 中,只需要在配置文件中引入相关依赖,然后使用 CommonsMultipartResolver 即可自动将文件上传流转化为 MultipartFile,方便操作。

三、文件下载

3.1 概述

文件下载功能比文件上传要简单得多。在 Spring 中,可以通过在响应头中设置 Content-Disposition 头,浏览器就会自动弹出下载框,提示用户下载文件。同时,还需要将文件的字节流写入响应体中。

3.2 示例

实现文件下载的示例代码如下:

@Controller
public class FileDownloadController {

    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String fileName = "myFile.jpg";
        String filePath = "C:/temp/" + fileName;
        File file = new File(filePath);

        if (file.exists()) {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) > 0) {
                os.write(buffer, 0, len);
            }
            os.flush();
            os.close();
            fis.close();
        } else {
            response.getWriter().write("文件不存在!");
        }
    }

}

文件下载请求的处理函数为 download(),在其中通过 Content-Disposition 头和响应的输出流向浏览器返回文件内容,实现文件下载功能。

四、总结

本文介绍了如何使用 SpringMVC 实现文件上传和下载功能。对于文件上传功能,我们讲解了基础示例和进阶示例,通过表单标签库的使用,限制文件上传的大小和类型,同时支持多个文件上传。对于文件下载功能,我们通过设置响应头和响应体中的字节流向浏览器返回文件内容,实现了文件下载功能。

以上便是“SpringMVC教程之文件上传与下载详解”的完整攻略。

本文标题为:SpringMVC教程之文件上传与下载详解

基础教程推荐