四、上传与下载
1. 导入文件上传jar包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5fpDJsJ3-1619746061969)(images/mvc_upload_jar.jpg)]
maven依赖配置
<dependencies>
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring对web的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springwebMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- 配置javaweb环境 -->
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
2. 配置
- SpringMVC为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的
- SpringMVC用Commons FileUpload技术实现了一个实现类:CommonsMultipartResovler
- SpringMVC中默认没有装配MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用需要配置CommonsMultipartResovler
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- springmvc的注解式开发 -->
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.newcapec.controller"/>
<!-- MVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 文件上传的属性设置 -->
<!-- 设置上传文件的大小: 文件的总字节数 -->
<property name="maxUploadSize" value="104857600"/>
<!-- 设置上传的字符编码 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 设置缓存大小 -->
<property name="maxInMemorySize" value="10240"/>
</bean>
</beans>
3. 页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>首页</h1>
<p><a href="views/upload.jsp">文件上传</a></p>
<p><a href="views/uploads.jsp">批量上传</a></p>
<p><a href="views/show.jsp">文件展示</a></p>
<p><a href="views/download.jsp">文件下载</a></p>
</div>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>上传成功!!!</h1>
</div>
</body>
</html>
upload.jsp
- form表单提交类型改为enctype=“multipart/form-data”
- 提交方式为post请求,method=“post”
- 在表单中添加type="file"的input表单元素,用来选择需要上传的文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>文件上传</h1>
<!--
在前端或页面中需要注意的:
1.文件上传时提交的请求方法必须为post
2.在form标签中enctype
enctype="application/x-www-form-urlencoded"为默认值:将数据转换为key/value格式,用于普通数据的提交
上传时需要修改enctype为enctype="multipart/form-data": 告知服务器请求中包含二进制的数据(文件)
3.使用上传组件(上传表单元素) <input type="file">
-->
<form action="upload.do" method="post" enctype="multipart/form-data">
<p>请选择文件:<input type="file" name="file"></p>
<p><button>上传</button></p>
</form>
</div>
</body>
</html>
4. Controller
在Controller的方法中添加MultipartFile类型的参数,用来接收上传文件
@Controller
public class UploadController {
/**
* 文件上传: 将本地文件传输至服务端
* 在springmvc中通过MultipartFile对象来接收上传的文件
* MultipartFile对象就是通过文件上传解析器创建的
*/
@RequestMapping("/upload.do")
public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
/**
* 处理上传文件:
* 1.获取文件的基本信息
* 2.指定文件的保存目录
* 3.防止文件名称重复
* 4.复制文件
*/
//获取文件大小
long fileSize = file.getSize();
//获取文件名称
String fileName = file.getOriginalFilename();
System.out.println(fileSize);
System.out.println(fileName);
/**
* 2.指定文件的保存目录
* 第一种:当前项目目录下(不是工作空间中,而是项目发布后的目录)
* 优点:属于项目内部资源,方便访问
* 问题:文件在项目中,如果文件数据量大,不利于项目迁移
* 第二种:服务器的文件系统中的目录
* 优点:项目资源与上传文件分离
* 问题:无法直接访问,需要配置虚拟目录,或搭建文件服务器
*/
String rootPath = request.getServletContext().getRealPath("/upload");
// String rootPath = "c:/upload";
/**
* 3.防止文件名称重复
* 使用新建目录,分开存放文件
* 使用UUID来生成新的文件名称
*/
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy");
SimpleDateFormat sdf2 = new SimpleDateFormat("MM");
Date today = new Date();
String year = sdf1.format(today);
String month = sdf2.format(today);
File dir = new File(rootPath + "/" + year + "/" + month);
if(!dir.exists()){
dir.mkdirs();
}
String newName = UUID.randomUUID().toString().replace("-","") +
fileName.substring(fileName.lastIndexOf("."));
//目标文件
File resultFile = new File(dir.getAbsolutePath() + "/" + newName);
//文件传输
file.transferTo(resultFile);
System.out.println("文件上传成功...");
return "success";
}
}
MultipartFile类中常用方法如下:
方法 | 作用 |
---|---|
getOriginalFilename() | 获取上传文件的原名 |
getSize() | 获取文件的字节大小,单位byte |
transferTo(File dest) | 通过i/o流,将文件存放到指定位置 |
getName() | 获取表单中文件组件的名字 |
getContentType() | 获取文件MIME类型 |
getInputStream() | 获取文件流 |
isEmpty() | 是否为空 |
处理上传文件:
- 文件的保存目录
- 第一种:当前项目目录下(不是工作空间中,而是项目发布后的目录)
优点:属于项目内部资源,方便访问
问题:文件在项目中,如果文件数据量大,不利于项目迁移 - 第二种:服务器的文件系统中的目录
优点:项目资源与上传文件分离
问题:无法直接访问,需要配置虚拟目录,或搭建文件服务器
- 第一种:当前项目目录下(不是工作空间中,而是项目发布后的目录)
- 防止文件名称重复
- 使用新建目录,分开存放文件
- 使用UUID来生成新的文件名称
5. 批量上传
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<h1>批量上传</h1>
<form action="uploadBatch.do" method="post" enctype="multipart/form-data">
<p>请选择文件1:<input type="file" name="file"></p>
<p>请选择文件2:<input type="file" name="file"></p>
<p>请选择文件3:<input type="file" name="file"></p>
<p><button>上传</button></p>
</form>
</div>
</body>
</html>
接收上传文件的参数为MultipartFile类型的数组即可
/**
* 批量上传
* 将MultipartFile对象定义为数组类型
*/
@RequestMapping("/uploadBatch.do")
public String uploadBatch(MultipartFile[] file) throws IOException {
for (MultipartFile multipartFile : file) {
multipartFile.transferTo(new File("c:/upload/" + multipartFile.getOriginalFilename()));
}
System.out.println("批量上传成功...");
return "success";
}
6. 下载
download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<a href="download.do?name=a.jpg">图片1</a>
<a href="download.do?name=b.jpg">图片2</a>
<a href="download.do?name=c.jpg">图片3</a>
<a href="download.do?name=中文.txt">文件</a>
</div>
</body>
</html>
设置响应头即可
@Controller
public class DownloadController {
/**
* 文件下载:将服务端的文件传输至客户端
* 页面无需跳转,需要设置下载响应头
*/
@RequestMapping("/download.do")
public void download(String name, HttpServletResponse response) throws Exception {
/**
* 设置下载响应头
* 1.content-disposition对应的值为attachment
* 告知浏览器客户端,响应为回传文件(附件)
* 2.设置下载时文件名称
* "attachment;fileName="+name
* 3.文件名称中文处理
* 使用URLEncoder对象进行转码
*/
// response.addHeader("content-disposition", "attachment");
// response.addHeader("content-disposition", "attachment;fileName="+name);
String filename = URLEncoder.encode(name,"UTF-8");
response.addHeader("content-disposition", "attachment;fileName="+filename);
//通过流进行文件传输
FileInputStream inputStream = new FileInputStream("c:/upload/" + name);
OutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
while(inputStream.read(buffer) != -1) {
outputStream.write(buffer);
}
outputStream.flush();
inputStream.close();
outputStream.close();
}
}
7. 加载资源
show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>图片展示</h1>
<p><img src="upload/a.jpg"></p>
<p><img src="/up/a.jpg"></p>
<p><img src="/up/b.jpg"></p>
<p><img src="/up/c.jpg"></p>
</div>
</body>
</html>
在页面中无法访问物理目录(硬盘中的真实目录),所以需要在服务器中配置相对应的虚拟目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6odaeWeA-1619746061973)(images/mvc_img.jpg)]
在eclipse中配置
-
双击服务列表中的tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aO36YAVA-1619746061975)(images/mvc_eclipse_servers.jpg)] -
打开tomcat配置的Modules
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FjRHjRfF-1619746061984)(images/mvc_eclipse_tomcat.jpg)] -
在Web Modules中配置虚拟路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAhRcOrS-1619746061986)(images/mvc_eclipse_modules.jpg)]
在idea中配置
-
在菜单栏找到Run菜单,选择其中的Edit Configurations…
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lGTD8UP8-1619746061987)(images/mvc_idea_run.jpg)] -
选择Deployment选项卡,点击加号,选择External Source…
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W9nqj38H-1619746061991)(images/mvc_idea_tomcat.jpg)] -
选择虚拟路径对应的物理目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3l8GRV4y-1619746061993)(images/mvc_idea_dir.jpg)] -
在Application context中配置虚拟路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bZU9r5D-1619746061994)(images/mvc_idea_context.jpg)]
在tomcat中配置
在配置目录conf的server.xml文件中找到<Host>标签,在其中添加如下代码即可。docBase为物理目录,path为虚拟路径
<Context docBase="c:\upload" path="/up" reloadable="true"/>