SpringMVC 文件上传和下载

1、文件上传

在Spring MVC中实现文件上传十分方便,它为文件上传提供了直接的支持,即MultipartResolver(多部件解析器)接口。MultipartResolver用于处理上传请求,将上传请求包装成可以直接获取文件的数据,从而方便操作。它有两个实现类:

  • StandardServletMultipartResolver
  • CommonsMultipartResolver

springmvc实现layui上传文件_spring

1.1、单文件上传

下面使用CommonsMultipartResolver实现单文件的上传功能

springmvc实现layui上传文件_servlet_02

(1) 下载并添加jar包,访问 http://commons.apache.org/proper/,
下载commons-fileupload-1.3.3.jar和commons-io-2.6.jar。

(2) 在Spring MVC配置文件中配置CommonsMultipartResolver类

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        ">
  <!-- 配置自动扫描的包 -->
  <context:component-scan base-package="com.springmvc"/>
  <!-- 自动注册处理器映射器和处理器适配器 -->
  <mvc:annotation-driven/>
  
  <!-- 配置视图解析器,将控制器方法返回的逻辑视图解析为物理视图 -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/ch10/"></property>
  <property name="suffix" value=".jsp"></property>
  </bean>  
  
  <!-- 如果不想经过控制器类的处理方法直接转发到页面,可以通过mvc:view-controller元素来实现 -->
  <mvc:view-controller path="/success" view-name="success"/>  
  <mvc:view-controller path="/index" view-name="index"/>
  
  <bean  class="org.springframework.web.servlet.view.BeanNameViewResolver">
  <property name="order" value="50"></property>
  </bean>
  
  <mvc:default-servlet-handler/>
  
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 上传文件的最大尺寸为1MB -->
    <property name="maxUploadSize" value="1048576"/>
    <!-- 字符编码 -->
    <property name="defaultEncoding" value="UTF-8"/>
  </bean>
 </beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
id="WebApp_ID" version="3.1">

<!-- 编码过滤器 -->
	 <filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
    	<filter-name>characterEncodingFilter</filter-name>
    	<url-pattern>/*</url-pattern>
  	</filter-mapping>

  <!-- 配置springmvc的前端控制器DispatcherServlet -->
  <servlet>
   <servlet-name>dispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!-- 初始化参数,配置Spring MVC配置文件的位置和名称 -->
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
  </init-param>
  <!-- 表示容器在启动时,立即加载 DispatcherServlet-->
  <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 让Spring MVC的前端控制器拦截所有请求 -->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>  
</web-app>

(3) 在ch10文件夹中新建index.jsp页面,并在该页面上创建一个表单,用于上传文件。提交表单后,以POST方式提交到一个名为“/fileUpload”的请求中。新建success.jsp页面,添加用于访问保存到request中的fileUrl值。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="../fileUpload">
选择文件:<input type="file" name="file"/><br/><br/>
<input type="submit" value="上传"/><br/><br/>
</form>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
文件上传成功!<br/>
上传文件的路径:${requestScope.fileUrl }
</body>
</html>

(4) 在com.springmvc.controller包中新建FileUploadController类,并在其中添加方法fileUpload,处理文件上传。

package com.springmvc.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadController {
   
	@RequestMapping(value="/fileUpload")
	public String fileUpload(@RequestParam(value="file",required=false)MultipartFile file,
			HttpServletRequest request,ModelMap modelMap){
		//服务器端upload文件夹物理路径
		String path=request.getSession().getServletContext().getRealPath("upload");
		//获取文件名
		String fileName=file.getOriginalFilename();
		//实例化一个file对象,表示目标文件,包含物理路径
		File targetFile=new File(path,fileName);
		if(!targetFile.exists()) {
			//创建文件
			targetFile.mkdirs();
		}
		try {
			//将上传文件写到服务器上的指定文件
			file.transferTo(targetFile);
		}catch(Exception e) {
			e.printStackTrace();
		}
		modelMap.put("fileUrl", request.getContextPath()+"/upload/"+fileName);
		return "success";
	}
}

(5) 部署springmvc-5,启动Tomcat,浏览http://localhost:8080/springmvc-5/ch10/index.jsp页面。

springmvc实现layui上传文件_servlet_03

选择文件上传

springmvc实现layui上传文件_mvc_04


查看上传文件

springmvc实现layui上传文件_spring_05

1.2、多文件上传

如果想通过浏览文件时,一次选择多个文件上传,可通过对方法参数中参数设置为@RequestParam(“files”) MultipartFile[] files的数组形式,这样可提交多个文件。

随着HTML 5的广泛应用,可利用移动端HTML 5的特性,一个input一次性选择多张图片的选择方式以前端设计为主,下面来介绍HTML 5的方式实现多文件上传,过程如下:

(1) 在springmvc-5项目的ch10的文件中,新建fileUpload.jsp,新建error.jsp页面,提示“文件上传失败,请重新上传!”。

fileUpload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>利用HTML5实现多文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="../upload">
	文件描述:<input type="text" name="description"/><br/><br/>
	<!-- 多文件选择属性multiple="multiple" -->
	选择文件:<input type="file" name="files" multiple="multiple"/><br/><br/>
	<input type="submit" value="上传"/><br/><br/>
</form>
</body>
</html>

error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传失败</title>
</head>
<body>
文件上传失败,请重新上传!<br/>
</body>
</html>

(2) 在控制器类FileUploadController中,添加upload()方法。

@RequestMapping(value="/upload")
	public String upload(@RequestParam(value="description") String description,
			@RequestParam(value="files",required=false) List<MultipartFile> files,
			HttpServletRequest request){
		//判断文件上传是否存在
		if(!files.isEmpty()&&files.size()>0) {
			//循环输出上传文件
			for(MultipartFile file:files) {
				//获取上传的原始文件名称
				String originalFileName=file.getOriginalFilename();
				//获取上传文件的保存地址目录
				String dirPath=request.getServletContext().getRealPath("/upload/");
				File filePath=new File(dirPath);
				//如果保存的文件的地址不存在,就先创建目录
				if(!filePath.exists()) {
					filePath.mkdirs();
				}
				//使用uuid重命名上传的新文件名(文件描述_uuid_原始文件名称)
				String newFileName=description+"_"+UUID.randomUUID()+"_"+originalFileName;
				try {
					file.transferTo(new File(dirPath+newFileName));
				}catch(Exception e) {
					e.printStackTrace();
					return "error";
				}
			}
			return "success";
		}
		return "error";
	}

(3) 重启Tomcat,浏览http://localhost:8080/springmvc-5/ch10/fileUpload.jsp 地址。
在上传页面中,填入文件描述,单击浏览按钮,选择所要上传的文件,单击“上传”按钮。

springmvc实现layui上传文件_mvc_06


springmvc实现layui上传文件_spring_07


查看文件

springmvc实现layui上传文件_tomcat_08

2、文件下载

文件下载就是将文件服务器中的文件下载到本机上,相对比较简单,直接在页面给出了一个超链接,该链接href的属性等于要下载文件的文件名,就可以实现文件下载了。但是如果该文件的文件名为中文文件名,在某些早起的浏览器上就会导致下载失败;如果使用最新的Firefox、Chrome等浏览器则都可以正常下载文件名为中文的文件了。修改上小节单文件上传的示例,实现文件下载,步骤如下:

(1) 修改FileUploadController类中的fileUpload()方法。

@RequestMapping(value="/fileUpload")
	public String fileUpload(@RequestParam(value="file",required=false)MultipartFile file,
			HttpServletRequest request,ModelMap modelMap){
		//服务器端upload文件夹物理路径
		String path=request.getSession().getServletContext().getRealPath("upload");
		//获取文件名
		String fileName=file.getOriginalFilename();
		//实例化一个file对象,表示目标文件,包含物理路径
		File targetFile=new File(path,fileName);
		if(!targetFile.exists()) {
			//创建文件
			targetFile.mkdirs();
		}
		try {
			//将上传文件写到服务器上的指定文件
			file.transferTo(targetFile);
		}catch(Exception e) {
			e.printStackTrace();
		}
		modelMap.put("fileUrl", request.getContextPath()+"/upload/"+fileName);
		modelMap.put("fileName",fileName);
		return "success";
	}

(2) 修改success.jsp页面,添加一个文件下载的超链接。

<a href="fileDownLoad?fileName=${requestScope.fileName }">${requestScope.fileName }</a>

(3) 在后台FileUploadController类中,添加fileDownload()的方法,并进行相应的映射。

@RequestMapping(value="/fileDownLoad")
   public ResponseEntity<byte[]> fileDownLoad(HttpServletRequest request,
   		@RequestParam(value="fileName") String fileName,Model model) throws Exception{
   	//下载文件路径
   	String path=request.getServletContext().getRealPath("/upload/");
   	//创建文件对象
   	File file=new File(path+File.separator+fileName);
   	//设置响应头
   	HttpHeaders headers=new HttpHeaders();
   	//下载显示的文件名,解决中文名乱码问题
   	String downLoadFileName=new String(fileName.getBytes("UTF-8"),"ISO8859-1");
   	//通知浏览器以下载方式(attachment)打开文件
   	headers.setContentDispositionFormData("attachment",downLoadFileName);
   	//定义以二进制流的形式下载返回的文件数据
   	headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
   	//使用SpringMVC框架的ResponseEntity封装返回的下载数据
   	byte[] bytes=FileUtils.readFileToByteArray(file);
   	return new ResponseEntity<byte[]>(bytes,headers,HttpStatus.CREATED);	
   }

(4) 重启Tomcat,浏览http://localhost:8080/springmvc-5/ch10/
index.jsp 地址,上传文件成功后,在页面上进行下载。

springmvc实现layui上传文件_tomcat_09


springmvc实现layui上传文件_spring_10


springmvc实现layui上传文件_web_11