在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);
}
}