八 文件上传与下载
1 文件上传
在 SpringMVC 中提供了用于处理文件上传的组件 CommonsMultipartResolver(多部件解 析器)。可以通过该组件很方便的实现文件上传。该组件的运行需要依赖于 Apache 的 commons-fileupload 与 commons-io 包。
文件上传就是,本地文件通过浏览器复制一份到服务器目录!
1.1搭建环境
1.1.1 创建项目并添加 jar 包
1.1.2 添加 springmvc 配置文件
<?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:context="http://www.springframework.org/schema/context"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.bjsxt.web.controller"/>
<mvc:annotation-driven/>
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--多部件解析器的id必须是multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件上传总容量。单位字节10M=10*1024*1024=10485760字节-->
<property name="maxUploadSize" value="181402917"/>
<!--设置文件名的编码方式-->
<property name="defaultEncoding" value="utf-8"/>
</bean>
</beans>
1.1.3 配置前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</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>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.2实现单文件上传
1.2.1 修改项目的访问路径
1.2.2 创建文件上传页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/12/6
Time: 18:55
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/singleFile" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" id=""/><br/>
文件上传: <input type="file" name="file"/><br/>
<input type="submit" value="ok">
</form>
</body>
</html>
1.2.3 创建成功页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/12/6
Time: 18:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
ok...
</body>
</html>
1.2.4 创建页面跳转控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/page")
public class PageController {
/**
* 跳转单文件上传页面
* @return
*/
@RequestMapping("/single")
public String showSingleFile(){
return "singlefile";
}
/**
* 跳转成功页面
* @return
*/
@RequestMapping("/ok")
public String showOk(){
return "ok";
}
1.3实现文件上传
1.3.1 创建文件上传控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.UUID;
@Controller
@RequestMapping("file")
public class FileUploadController {
/**
* 实现单文件上传
* @param file
* @param username
* @param request
* @return
*/
@RequestMapping("singleFile")
public String singleFile(MultipartFile file, String username, HttpServletRequest request) {
String fileName = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
System.out.println(fileName);
String realPath = request.getServletContext().getRealPath("/fileupload");
System.out.println(realPath);
File temp = new File(realPath,fileName);
try {
// 将浏览器传递过来的文件保存到项目的运行目录temp下
file.transferTo(temp);
}catch (Exception e) {
e.printStackTrace();
}
return "redirect:/page/ok";
}
}
1.4实现多文件上传
1.4.1 创建多文件上传页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/12/6
Time: 19:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/multiFile" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" id=""/><br/>
文件上传1: <input type="file" name="file"/><br/>
文件上传2: <input type="file" name="file"/><br/>
<input type="submit" value="ok">
</form>
</body>
</html>
1.4.2 创建页面跳转方法
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/page")
public class PageController {
/**
* 跳转单文件上传页面
* @return
*/
@RequestMapping("/single")
public String showSingleFile(){
return "singlefile";
}
/**
* 跳转成功页面
* @return
*/
@RequestMapping("/ok")
public String showOk(){
return "ok";
}
/**
* 跳转多文件上传页面
* @return
*/
@RequestMapping("/multi")
public String showMultiFile(){
return "multifile";
}
}
1.5实现多文件上传
1.5.1 创建文件上传控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.UUID;
@Controller
@RequestMapping("file")
public class FileUploadController {
/**
* 实现单文件上传
* @param file
* @param username
* @param request
* @return
*/
@RequestMapping("singleFile")
public String singleFile(MultipartFile file, String username, HttpServletRequest request) {
String fileName = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
System.out.println(fileName);
String realPath = request.getServletContext().getRealPath("/fileupload");
System.out.println(realPath);
File temp = new File(realPath,fileName);
try {
// 将浏览器传递过来的文件保存到项目的运行目录temp下
file.transferTo(temp);
}catch (Exception e) {
e.printStackTrace();
}
return "redirect:/page/ok";
}
@RequestMapping("multiFile")
public String multiFile(MultipartFile file[], String username, HttpServletRequest request) {
for(MultipartFile temp : file) {
String fileName = UUID.randomUUID().toString()+temp.getOriginalFilename().substring(temp.getOriginalFilename().lastIndexOf("."));
System.out.println(fileName);
String realPath = request.getServletContext().getRealPath("/fileupload");
System.out.println(realPath);
File f = new File(realPath,fileName);
try {
// 将浏览器传递过来的文件保存到项目的运行目录temp下
temp.transferTo(f);
}catch (Exception e) {
e.printStackTrace();
}
}
return "redirect:/page/ok";
}
}
运行结果:
单文件:
通过控制器访问上传单个文件camera.sql的页面:
点击ok,浏览器提交form表单数据到/file/singleFile控制器
使用transferTo将来自客户端主机的文件复制一份到服务器中项目运行的目录下。完成后重定向到成功页面。服务器目录中文件,就是camera.sql文件。避免充重名使用java工具uuid生成随机的新名字,后缀名与源文件一致。
多文件上传运行结果:
通过控制器访问多文件上传页面。上传两张图片,如图。
点击ok.浏览器发送表单数据到文件上传控制器。
使用MultipartFile[]数据接受多个文件。名称必须一致,jsp表单中的Input名称必须与请求参数中的MUltipartFile[]名称一致。否则使用@RequestParam注解绑定。其中jsp中多个文件的Inp的名字要一样。
使用for循环处理每一个文件,将文件保存到服务器目录下,然后重定向到成功页面。
2 文件下载
2.1显示下载文件
2.1.1 添加 JSTL 标签库 jar 包
jstl.jar
standard.jar
2.1.2 创建下载页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2020/12/7
Time: 8:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:forEach items="${files}" var="file">
<a href="/file/fileDown?fileName=${file}">${file}</a><br/>
</c:forEach>
</body>
</html>
2.1.3 创建跳转下载页面方法
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
@Controller
@RequestMapping("/page")
public class PageController {
/**
* 跳转单文件上传页面
* @return
*/
@RequestMapping("/single")
public String showSingleFile(){
return "singlefile";
}
/**
* 跳转成功页面
* @return
*/
@RequestMapping("/ok")
public String showOk(){
return "ok";
}
/**
* 跳转多文件上传页面
* @return
*/
@RequestMapping("/multi")
public String showMultiFile(){
return "multifile";
}
/**
* 跳转文件下载的页面
* @return
*/
@RequestMapping("/showFileDown")
public String showFileDown(HttpServletRequest request, Model model){
String realPath = request.getServletContext().getRealPath("/fileupload");
File file = new File(realPath);
String[] arr = file.list();
model.addAttribute("files",arr);
return "filedown";
}
}
2.2下载文件
2.2.1创建文件下载控制器
package com.bjsxt.web.controller;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.UUID;
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* 实现单文件上传
* @param file
* @param username
* @param request
* @return
*/
@RequestMapping("/singleFile")
public String singleFile(MultipartFile file, String username, HttpServletRequest request) {
String fileName = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
System.out.println(fileName);
String realPath = request.getServletContext().getRealPath("/fileupload");
System.out.println(realPath);
File temp = new File(realPath,fileName);
try {
// 将浏览器传递过来的文件保存到项目的运行目录temp下
file.transferTo(temp);
}catch (Exception e) {
e.printStackTrace();
}
return "redirect:/page/ok";
}
@RequestMapping("/multiFile")
public String multiFile(MultipartFile file[], String username, HttpServletRequest request) {
for(MultipartFile temp : file) {
String fileName = UUID.randomUUID().toString()+temp.getOriginalFilename().substring(temp.getOriginalFilename().lastIndexOf("."));
System.out.println(fileName);
String realPath = request.getServletContext().getRealPath("/fileupload");
System.out.println(realPath);
File f = new File(realPath,fileName);
try {
// 将浏览器传递过来的文件保存到项目的运行目录temp下
temp.transferTo(f);
}catch (Exception e) {
e.printStackTrace();
}
}
return "redirect:/page/ok";
}
@RequestMapping("/fileDown")
public void fileDown(String fileName, HttpServletRequest request, HttpServletResponse response) {
// 设置响应头
response.setHeader("Content-Disposition","attachment;filename="+fileName);
// 获取绝对路径
String realPath = request.getServletContext().getRealPath("/fileupload");
File file = new File(realPath,fileName);
// 获取字节输出流
try{
ServletOutputStream outputStream = response.getOutputStream();
// 读文件 FileUtils.readFileToByteArray(file)
outputStream.write(FileUtils.readFileToByteArray(file));
outputStream.flush();
outputStream.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
运行结果通过控制器显示服务器中的文件列表,超链接中写文件下载的控制器路径,点击,调用,输出流写字节流到浏览器中。