11、SpringMVC:文件上传和下载
2020-12-30 05:29
标签:common 设置 query origin ext base 一个 api comm 引用学习 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。 前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器; 对表单中的 enctype 属性做个详细的说明: application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。 multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。 text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。 一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。 在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。 Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。 而Spring MVC则提供了更简单的封装。 Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。 Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。 一、导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包; 二、配置bean:multipartResolver 【注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!】 CommonsMultipartFile 的 常用方法: String getOriginalFilename():获取上传文件的原名 InputStream getInputStream():获取文件流 void transferTo(File dest):将上传文件保存到一个目录文件中 我们去实际测试一下 三、编写前端页面 四、Controller 五、响应页面 六、测试上传文件,OK!
1、编写Controller 2、前端表单提交地址修改 3、访问提交测试,OK! 一、导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包; 二、配置bean:multipartResolver 【注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!】 CommonsMultipartFile 的 常用方法: String getOriginalFilename():获取上传文件的原名 InputStream getInputStream():获取文件流 void transferTo(File dest):将上传文件保存到一个目录文件中 我们去实际测试一下 三、编写前端页面 四、Controller 五、测试上传文件,OK! 1、编写Controller 2、前端表单提交地址修改 3、访问提交测试,OK! 文件下载步骤: 设置 response 响应头 读取文件 -- InputStream 写出文件 -- OutputStream 执行操作 关闭流 (先开后关) 在图片上添加标签请求后台,进行下载
1、准备工作
form action="" enctype="multipart/form-data" method="post">
input type="file" name="file"/>
input type="submit">
form>
2、文件上传
单文件上传
1)使用IO流手动实现文件上传
dependency>
groupId>commons-fileuploadgroupId>
artifactId>commons-fileuploadartifactId>
version>1.3.3version>
dependency>
dependency>
groupId>javax.servletgroupId>
artifactId>javax.servlet-apiartifactId>
version>4.0.1version>
dependency>
bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
property name="defaultEncoding" value="utf-8"/>
property name="maxUploadSize" value="10485760"/>
property name="maxInMemorySize" value="40960"/>
bean>
@ page contentType="text/html;charset=UTF-8" language="java" %>
@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
html>
head>
title>Titletitle>
head>
body>
h1>上传成功h1>
c:forEach items="${urls}" var="url">
img src="${url}" style="width: 300px; height: 200px;">
c:forEach>
body>
html>
@Controller
public class FileController {
private static final String PATH = "/upload/";
/**
* 文件上传(单文件上传)
* @param file
* @param request
* @return
* @throws IOException
*/
@RequestMapping("/upload1")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request, Model model) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
?
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
// 时间路径
String dateFormat = getTimePath();
//上传路径保存设置
String path = request.getServletContext().getRealPath(PATH) + dateFormat;
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
?
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath, uploadFileName)); //文件输出流
?
//读取写出
int len = 0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer, 0, len);
os.flush();
}
os.close();
is.close();
// 上传成功后,拼接文件在服务器上的路径
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + PATH + dateFormat + uploadFileName;
System.out.println(url);
model.addAttribute("urls", Arrays.asList(url));
return "ok";
}
// 按上传时间设置路径
public String getTimePath(){
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/");
String dateFormat = format.format(new Date());
return dateFormat;
}
?
}
@ page contentType="text/html;charset=UTF-8" language="java" %>
@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
html>
head>
title>Titletitle>
head>
body>
h1>上传成功h1>
c:forEach items="${urls}" var="url">
img src="${url}" style="width: 300px; height: 200px;">
c:forEach>
body>
html>
2)采用file.Transto 来保存上传的文件
/*
* 采用file.Transto 来保存上传的文件
*/
// 使用SpringMVC提供的方法上传文件(单文件上传)
@RequestMapping("/upload3")
public String fileUploads2(@RequestParam("file") MultipartFile file, HttpServletRequest request, Model model){
try {
String url = upload(file, request);
model.addAttribute("urls", Arrays.asList(url));
return "ok";
} catch (IOException e) {
return "redirect:/index.jsp";
}
}
// 文件上传方法,单文件上传
public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
String dateFormat = getTimePath(); // 时间路径
// 用随机UUID作为文件名
String oldFileName = file.getOriginalFilename();
String newFileName = UUID.randomUUID().toString().replaceAll("-", "") +
oldFileName.substring(oldFileName.lastIndexOf("."));
// 获取项目在服务器上的路径,下面的路径为:项目在服务器上的路径/upload/2020/05/
String realPath = request.getServletContext().getRealPath(PATH) + dateFormat;
// 如果将要保存文件的目录不存在则创建
File direcotry = new File(realPath);
if (!direcotry.exists()) direcotry.mkdirs();
// 拼接文件路径
realPath += newFileName;
// 文件上传
file.transferTo(new File(realPath));
// 上传成功后,拼接文件在服务器上的路径
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + PATH + dateFormat + newFileName;
return url;
}
// 按上传时间设置路径
public String getTimePath(){
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/");
String dateFormat = format.format(new Date());
return dateFormat;
}
多文件上传
1)使用IO流手动实现文件上传
dependency>
groupId>commons-fileuploadgroupId>
artifactId>commons-fileuploadartifactId>
version>1.3.3version>
dependency>
dependency>
groupId>javax.servletgroupId>
artifactId>javax.servlet-apiartifactId>
version>4.0.1version>
dependency>
bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
property name="defaultEncoding" value="utf-8"/>
property name="maxUploadSize" value="10485760"/>
property name="maxInMemorySize" value="40960"/>
bean>
@ page contentType="text/html;charset=UTF-8" language="java" %>
html>
head>
title>$Title$title>
script src="${pageContext.request.contextPath}/statics/js/jquery-3.3.1.js">script>
script>
function check() {
var f1 = document.getElementById("f1").files;
var f2 = document.getElementById("f2").files;
if (f1[0].size + f2[0].size > 1024 * 1024 * 10){
alert("文件总和过大");
return false;
}else{
return true;
}
}
function getFileSize(file) {
var fileSize = file.files[0].size;
if (fileSize > 1024 * 1024 * 10) {
alert("文件大小不能超过10M,请重新选择文件"); // 提示消息
$(file).val(""); // 清空已选择的文件
}
}
script>
head>
body>
?
form action="${pageContext.request.contextPath}/upload2" method="post" enctype="multipart/form-data" onsubmit="return check()">
input type="file" name="file" id="f1" onchange="getFileSize(this)">br/>
input type="file" name="file" id="f2" onchange="getFileSize(this)">br/>
input type="submit" value="上传">
-- 或者添加multiple属性,可以直接选择一个或者多个文件上传 --%>
--form action="/upload4" method="post" enctype="multipart/form-data">--%>
--input type="file" name="file" multiple>--%>
--input type="submit" value="上传">--%>
--form>--%>
form>
?
body>
html>
package com.zxh.controller;
?
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
?
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
?
@RestController
public class FileController {
// CommonsMultipartFile 实现了MultipartFile解耦
// 手动实现文件上传(多文件上传)
@RequestMapping("/upload2")
public String fileUploads(@RequestParam("file") MultipartFile[] files, HttpServletRequest request, Model model) throws IOException {
List
2)采用file.Transto 来保存上传的文件
/*
* 采用file.Transto 来保存上传的文件
*/
// 使用SpringMVC提供的方法上传文件(多文件上传)
@RequestMapping("/upload4")
public String fileUploads2(@RequestParam("file") MultipartFile[] files, HttpServletRequest request, Model model){
try {
List
3、文件下载
controller
// 文件下载
@RequestMapping("/download")
public void downloads(String url, HttpServletResponse response , HttpServletRequest request) throws Exception{
// 要下载的图片地址
String path = request.getServletContext().getRealPath(PATH);
url = url.replace("upload/", "");
// 获取文件名
String fileName = url.substring(url.lastIndexOf("/") + 1);
//1、设置response 响应头
response.reset(); //设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8"); //字符编码
response.setContentType("multipart/form-data"); //二进制传输数据
//设置响应头
response.setHeader("Content-Disposition",
"attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path, url);
//2、 读取文件--输入流
InputStream input=new FileInputStream(file);
//3、 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、执行 写出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
}
前端
@ page contentType="text/html;charset=UTF-8" language="java" %>
@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
html>
head>
title>Titletitle>
head>
body>
h1>上传成功h1>
c:forEach items="${urls}" var="url">
a href="/download?url=${url.substring(url.lastIndexOf("upload/"))}">img src="${url}" style="width: 300px; height: 200px;">a>
c:forEach>
body>
html>
测试,文件下载OK!
4、整合代码
项目结构
代码
controller
package com.zxh.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
@Controller
public class FileController {
private static final String PATH = "/upload/";
// 手动实现文件上传(单文件上传)
@RequestMapping("/upload1")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request, Model model) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
// 时间路径
String dateFormat = getTimePath();
//上传路径保存设置
String path = request.getServletContext().getRealPath(PATH) + dateFormat;
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath, uploadFileName)); //文件输出流
//读取写出
int len = 0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer, 0, len);
os.flush();
}
os.close();
is.close();
// 上传成功后,拼接文件在服务器上的路径
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + PATH + dateFormat + uploadFileName;
System.out.println(url);
model.addAttribute("urls", Arrays.asList(url));
return "ok";
}
// 手动实现文件上传(多文件上传)
@RequestMapping("/upload2")
public String fileUploads(@RequestParam("file") MultipartFile[] files, HttpServletRequest request, Model model) throws IOException {
List
文章标题:11、SpringMVC:文件上传和下载
文章链接:http://soscw.com/index.php/essay/39216.html