SpringMVC实现文件的上传与下载

SpringMVC的请求数据参数化的处理机制,使得上传中小型文件变得方便、快捷。在前端页面,与传统开发模式一样,使用标签来添加文件,同时为form表单设置:enctype="multipart/form-data" 的属性,当此类型的表单被提交后,SpringMVC会对multipart类型的数据进行解析。

1、MultipartFile类

在SpringMVC中,MultipartFile类主要用来接收并转换request请求中的multipart类型的文件数据。执行Controller获得MultipartFile类型的参数后,就可以使用该参数进行文件的处理了。

MultipartFile类的常用方法:

方法名 返回值 说明
getContentType() String 获取文件MIME类型。
getInputStream() InputStream 获取文件流。
getName() String 获取form表单中的文件组件的名字。
getOriginalFilename() String 获取上传文件的原名。
getSize() long 获取文件的大小,单位为byte。
isEmpty() boolean 判断文件是否为空。
transferTo(File dest) void 将数据保存到一个目标文件中。

 

2、实现文件的上传与下载

下面通过实现一个图片上传与下载的实例,来了解SpringMVC上传与下载文件的配置和操作,执行结果图如下:

SpringMVC实现文件的上传与下载_第1张图片

2.1 配置multipart类型解析器

使用SpringMVC上传文件,首先需要在SpringMVC的核心配置文件springmvc.xml中配置multipart类型解析器,具体配置语句如下:



    
    

注意:在该配置中,id="multipartResolver"属性是必须加上的,并且值是固定的。如果不加该id属性,则项目在运行时会报异常。

2.2 下载依赖的jar包

使用SpringMVC上传文件,其内部实现也使用Apache开源上传软件包fileupload与io包(如下图),所以要将这两个jar包的依赖引入工程中。下载地址如下:

commons-fileupload.jar下载地址

commons-io.jar下载地址

如果使用Maven,则pom.xml文件配置如下:



  commons-fileupload
  commons-fileupload
  1.4


  commons-io
  commons-io
  2.6

2.3 编写JSP页面

创建名为FileUpload.jsp的页面,编写上传图片的前端页面代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    SpringMVC实现文件上传与下载
    
    


SpringMVC实现文件上传与下载
图片显示:
上传文件:
上传用户:
下载文件: 下载文件
博客信息: 您好,欢迎访问 pan_junbiao的博客
博客地址: https://blog.csdn.net/pan_junbiao
<%=request.getAttribute("message") == null ? "" : request.getAttribute("message")%>

在该页面中,添加了一个包含enctype="multipart/form-data" 的属性的form表单,并且其中包含一个的文件上传标签。

2.4 编程Controller控制器

编写处理该上传与下载请求的Controller控制器类的方法。

package com.pjb.mvc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 文件上传与下载控制器
 * @author pan_junbiao
 **/
@Controller
@RequestMapping("file")
public class FileController
{
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    //目录名称
    private String _dirName = "/UploadImages/";

    /**
     * 上传文件
     */
    @RequestMapping("uploadFile")
    public String uploadFile(Model model, MultipartFile file, String userName)
    {
        try
        {
            if (file.isEmpty())
            {
                model.addAttribute("message", "请求选择要上传的文件");
                return "/FileUpload.jsp";
            }

            //上传的图片的原始名称
            String originalFilename = file.getOriginalFilename();

            //判断文件大小
            long size = file.getSize();
            if (size > 1048576)
            {
                model.addAttribute("message", "文件大于1M,不能上传");
                return "/FileUpload.jsp";
            }

            //获取文件后缀名,并转换为小写
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            //只能上传图片,过滤不可上传的文件类型
            String fileExit = ".jpg|.jpeg|.gif|.bmp|.png|";
            if (fileExit.indexOf(suffix) <= -1)
            {
                model.addAttribute("message", "对不起!请上传图片");
                return "/FileUpload.jsp";
            }

            //目录路径
            String dirPath = request.getServletContext().getRealPath(_dirName);

            //判断文件目录是否存在,不存在则创建
            File dirFile = new File(dirPath);
            if (!dirFile.exists())
            {
                dirFile.mkdirs();
            }

            //新的文件名称(格式为:yyyyMMddHHmmss+随机4位数+后缀名)
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); //设置日期格式
            int randomNum = (int) (1000 + Math.random() * (9999 - 1000 + 1)); //随机4位数
            String newFileName = df.format(new Date()) + randomNum + suffix;

            //上传文件
            File newFile = new File(dirPath+newFileName);
            file.transferTo(newFile);

            //返回成功
            model.addAttribute("message", "文件上传成功");
            model.addAttribute("newFileName", newFileName);
            return "/FileUpload.jsp";
        }
        catch (Exception ex)
        {
            model.addAttribute("message", "文件上传失败");
            return "/FileUpload.jsp";
        }
    }

    /**
     * 下载文件
     */
    @RequestMapping("downloadFile")
    public ResponseEntity downloadFile(String fileName)
    {
        try
        {
            if(fileName==null || fileName.length()==0)
            {
                return null;
            }
            request.setCharacterEncoding("UTF-8");
            //目录路径
            String dirPath = request.getServletContext().getRealPath(_dirName);
            //获取文件
            File file = new File(dirPath+fileName);
            //判断文件是否存在
            if(!file.exists())
            {
                return null;
            }
            //解决文件名乱码
            String downloadFileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
            //读取二进制文件
            byte[] body = null;
            InputStream is = new FileInputStream(file);
            body = new byte[is.available()];
            is.read(body);
            //通知浏览器以attachment(下载方式)打开图片
            response.setHeader("Content-Disposition", "attchement;filename=" + downloadFileName);
            //application/octet-stream二进制流数据(最常见的文件下载)。
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            //文件下载的Http协议中的状态最好使用HttpStatus.OK。
            HttpStatus statusCode = HttpStatus.OK;
            ResponseEntity entity = new ResponseEntity(body, statusCode);
            return entity;
        }
        catch (Exception ex)
        {
            ex.toString();
            return null;
        }
    }
}

 

3、上传多张图片

当需要上传多张图片时,可以在页面创建多个name相同的标签,这样就可以提交多张图片。或者利用移动端HTML5的特性,一个input一次性选择多张图片。多张图片的选择方式主要以前端设计为主,不过多介绍,这里主要介绍后台的处理逻辑,因为不论前端的图片选择模式如何,后台的上传处理逻辑是相同的。在处理图片上传的Controlller方法中,在参数中使用MultipartFile类的数组来接收相同name的文件资源,代码如下:

/**
 * 上传多个文件
 */
@RequestMapping("uploadFiles")
public String uploadFiles(Model model, @RequestParam("files") MultipartFile[] files)
{
    //利用数组的方式来处理多张图片,处理过程忽略...
}

注意:假设前端文件input的name为“files”,那么Controller方法中的MultipartFile数组的前面要添加@RequestParam("files")注解,表示解析所有名为files的文件资源,将其添加至MultipartFile数组(这里MultipartFile数组的名称仅为参数名称,可以任意命名),该注解不可以省略。

 

你可能感兴趣的:(#,Spring,MVC,我の原创,编程应用)