通过SpringMVC实现文件/多文件上传与下载案例

在web开发中一般会有文件上传的操作
一般JavaWeb开发中文件上传使用的 Apache组织的Commons FileUpload组件
SpringMVC中使用 MultipartFile file对象接受上传文件,必须保证 后台参数的名称和表单提交的文件的名称一致

文件上传必须条件
1.表单必须post
2.表单必须有 file 文件域
3.表单的 enctype=“multipart/form-data”

需要用到的jar包

在这里插入图片描述

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_4_0.xsd" id="WebApp_ID" version="4.0">
 
 
 
 <!-- 设置请求参数字符编码过滤 -->
	<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>
	</filter>	
	
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>\/*</url-pattern>
	</filter-mapping>
 
 

 <servlet>
 	<servlet-name>MVC</servlet-name>
 	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 	<init-param>
 		<param-name>contextConfigLocation</param-name>
 		<param-value>classpath:springmvc.xml</param-value>
 	</init-param>
 	<load-on-startup>1</load-on-startup>
 </servlet>
 
 	<servlet-mapping>
 		<servlet-name>MVC</servlet-name>
 		<url-pattern>*.do</url-pattern>
 	</servlet-mapping>
 
</web-app>

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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
		
	<!-- 包扫描 -->
	<context:component-scan base-package="com.ywq.springmvc"></context:component-scan>
	
	<!-- 注解驱动 -->	
	<mvc:annotation-driven/>
	
	<!-- 配置文件上传解析器 
		multipartResolver
		因为文件上传解析器是SpringMVC框架运行的非核心组件
		只有开发者使用时候才创建,一个项目中上传文件的地方偶尔也就一两个		
	-->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="#{1024*1024*5}"></property>
	</bean>
	
</beans>

后台jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
后台首页
</body>
</html>
文件上传jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
 <span style="color: red;">${msg}</span>
<fieldset>
		<legend>单个文件上传</legend>
		<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
			姓名: <input name="username"><br>
			头像: <input type="file" name="headImg"><br>
			<button type="submit">提交</button>
		</form>
	</fieldset>
	
	
	<fieldset>
		<legend>多个文件上传</legend>
		<form action="${pageContext.request.contextPath}/uploads.do" method="post" enctype="multipart/form-data">
			文件1: <input type="file" name="headImgs"><br>
			文件2: <input type="file" name="headImgs"><br>
			文件3: <input type="file" name="headImgs"><br>
			<button type="submit">提交</button>
		</form>
	</fieldset>

SpringMVC中使用 MultipartFile file对象接受上传文件,必须保证 后台方法MultipartFile 参数的名称和表单提交的文件的名称一致

文件上传控制层代码

package com.ywq.springmvc.controller;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadController {
	
	
	/*
	 * 
	 * SpringMVC框架已经对文件上传接收完成处理,是对Apache的FileUpload文件上传组件的集成
	 * 
	 * 开发之在接收上传的文件注入:MultipartFile即可
	 * 实现类:org.springframework.wbe.multipart.commons.CommonsMultipartFile
	 * 
	 * 注意:注入的参数名称必须和前台表单的名称一致
	 * 
	 * */
	
	private List<String> mimeTypes = Arrays.asList("image/jpeg","image/png");
	
	@RequestMapping("/upload")
	public String update( String username,MultipartFile headImg,Model m ) {
		System.out.println(username);
		System.out.println(headImg);
		System.out.println(headImg.getName());//表单名称	
		System.out.println(headImg.getOriginalFilename());//文件名称
		System.out.println(headImg.getContentType());//获取文件MIME类型
		
		/*
		 * 什么是MIME文件?
		 *  计算机上所有文件都有文件类型,这个文件类型就叫做MIME类型
		 *  MIME的格式 xxxx/xxx
		 *  
		 *  常见文件MIME类型
		 *  	.jpg --->image/jpeg
		 *  	.png --->image/png
		 *  	.html --->text/html
		 *  
		 *  使用MIME可以对文件上传的文件内容进行判断,比如:只能上传图片
		 * 
		 * */
		
		//文件类型判断
		if (!mimeTypes.contains(headImg.getContentType())) {
			m.addAttribute("msg", "文件必须是jpg或者png格式");
			return "/upload.jsp";
		}
		
		//将上传的文件保存到服务器的某一块磁盘位置
		//文件上传的目录
		File parent = new File("d:/linshi");
		if (!parent.exists()) {
			parent.mkdir(); //创建单级目录
			//parent.mkdirs()//创建多级目录
		}
		
		//获取上传的文件的后缀
		String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());
		
		//创建新的文件名称
		String newFilename = UUID.randomUUID().toString().replaceAll("-", "")+"."+extension;
		
		File dest = new File(parent, newFilename);
		
		try {
			//上传文件
			headImg.transferTo(dest);
		} catch (IllegalStateException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return "/main.jsp";
	}
	
	
	
	@RequestMapping("/uploads")
	public String updates( String username,MultipartFile[] headImgs,Model m ) {
		
		//将上传的文件保存到服务器的某一块磁盘位置
		//文件上传的目录
		File parent = new File("d:/linshi");
		if (!parent.exists()) {
			parent.mkdir(); //创建单级目录
			//parent.mkdirs()//创建多级目录
		}
		
		for (MultipartFile headImg : headImgs) {
			//文件类型判断
			if (!mimeTypes.contains(headImg.getContentType())) {
				m.addAttribute("msg", "文件必须是jpg或者png格式");
				return "/upload.jsp";
			}
			
			//获取上传的文件的后缀
			String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());
			
			//创建新的文件名称
			String newFilename = UUID.randomUUID().toString().replaceAll("-", "")+"."+extension;
			
			File dest = new File(parent, newFilename);
			
			try {
				//上传文件
				headImg.transferTo(dest);
			} catch (IllegalStateException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return "/main.jsp";
	}
}

文件下载,SpringMVC并没有做过多的封装,还是使用原来的下载方式

JavaWeb 开发中使用 ServletOutStream 向浏览器响应数据(输出流输出数据),就是下载文件

文件下载jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
	
	<h3>高清影视下载</h3>
	<a href="${pageContext.request.contextPath}/download.do?fileName=tiaoyins.mp4">调音师(生肉)</a><br>
	<a href="${pageContext.request.contextPath}/download.do?fileName=调音师.mp4">调音师(熟肉)</a><br>

文件下载控制层代码
package com.ywq.springmvc.controller;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

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

import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class DownloadController {

	/*
	 * 文件下载思路
	 * 
	 * 1.程序根据接收的文件名称找到磁盘对应的文件,读取内存中来(文件不能太大),形成一个输入流
	 *
	 * 2.通过Web开发中HttpServleResponse中获取输出流 ServletOutputStream将输入流响应给浏览器(下载)
	 * 2.1 设置Http协议响应头,告诉浏览器(现在不是普通默认渲染html,而是响应附件内容(下载))
	 * 
	 * */
	@RequestMapping("/download")
	public void download(String fileName,HttpServletResponse response,HttpServletRequest request) throws IOException {
		
		System.out.println("fileName:"+fileName);
		
	//1.程序根据接收的文件名称找到磁盘对应的文件,读取内存中来(文件不能太大),形成一个输入流
		InputStream inputStream = new FileInputStream("d:/linshi/"+fileName);
		
	//2.获取输出流
		ServletOutputStream outputStream = response.getOutputStream();
		
		/*
		 * 浏览器两个标准
		 * 
		 * IE:微软
		 * 
		 * W3C:万维网联盟(互联网标准组织)
		 * 	google浏览器
		 * 	firefox浏览器
		 * 	...
		 * 
		 * 	国产浏览器都是基于谷歌和IE开源内核封装一个壳子
		 * 
		 * 	文件下载的时候
		 * 	W3C响应给浏览器的文件名称编码是ISO-8859-1编码
		 * 	需要再响应给浏览器之前将文件编码转换成ISO-8859-1编码
		 * 
		 * 	IE
		 * 		UTF-8
		 * 
		 * */
		
		//获取请求头的User-Agent
		String userAgernt = request.getHeader("User-Agent");
		System.out.println(userAgernt);
		
		if (!userAgernt.contains("MSIE")) { //非IE浏览器
			//先将字符串转换成字节数组
			byte[] bytes = fileName.getBytes("UTF-8");
			
			//创建新的字符串:ISO-8859-1编码格式
			fileName = new String(bytes,"ISO-8859-1");
		}
		System.out.println("fileName:"+fileName);
		
	//2.1设置Http协议响应头,告诉浏览器(现在不是普通默认渲染html,而是响应附件内容(下载))
		response.setHeader("Content-Disposition", "attachment;filename="+fileName);
		
		/*
		 * commons-io-1.4.jar 工具包中有文件各种处理工具类
		 * 
		 * IOUtile:IO输入输出流工具类
		 * */
		
		IOUtils.copy(inputStream, outputStream);
		
		
		
	}
	
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章