文件的上传与下载
文件上传下载原理
在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。
但是在jsp编程中不能使用FTP方法来上传文件,这是由jsp运行机制所决定的
文件上传原理:
通过为表单元素设置Method=“post” enctype=“multipart/form-data”属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取到上传文件的内容,从而实现文件的上传。
文件下载原理:
STEP1
需要通过HttpServletResponse.setContextType方法设置Content-Type头字段的值,为浏览器无法使用某种方式或**某个程序来处理MIME类型,例如“application/octet-stream” 或 “application/x-msdownload” 等。
STEP2
需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为“attachment;filename=文件名”
STEP3
读取下载文件,通过HttpServletResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件内容。
上传具体实现代码
package com.cn.demo;
import org.springframework.web.bind.annotation.PostMapping;
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 java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@RestController
public class uploadTest {
public static final List<String> IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png",".docx",".xlsx);
public static String getUUID() {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
return uuid;
}
public static final String HH = "HH";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final DateTimeFormatter FORMATTER_HH = DateTimeFormatter.ofPattern(HH);
public static final DateTimeFormatter FORMATTER_YYYY_MM_DD = DateTimeFormatter.ofPattern(YYYY_MM_DD);
public static String getHH() {
return FORMATTER_HH.format(LocalDateTime.now());
}
public static String getYYYYMMDD() {
return FORMATTER_YYYY_MM_DD.format(LocalDateTime.now());
}
@PostMapping("/updateImage")
@ResponseBody
public Map<String, String> updateImage(@RequestParam("image") MultipartFile[] multfiles) {
Map<String, String> result = new HashMap<>();
//1、校验是否有图片
if (multfiles.length == 0) {
result.put("message", "请选择图片!");
return result;
}
final String originalFileName = multfiles[0].getOriginalFilename();
// if (StringUtils.isBlank(originalFileName)) {
// result.put("message", "请选择图片!");
// return result;
// }
//2、判断文件后缀[.jpg]
final String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")).toLowerCase();
if (!IMAGE_EXTENSIONS.contains(suffix)) {
result.put("message", "图片格式错误!");
return result;
}
//3、创建与拼接文件要存储的路径
String lastFilePath;
String newFileName = getUUID() + suffix;
String folderName = File.separator + "temp" + File.separator;
String relativePath = folderName + getYYYYMMDD() + File.separator + getHH();
String filePath = "D:\\fileImg" + relativePath;
String fileUrl = null;
File targetFile = new File(filePath);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
//4、创建输出流,去写输出流中
FileOutputStream out = null;
try {
lastFilePath = filePath + File.separator + newFileName;
out = new FileOutputStream(lastFilePath);
out.write(multfiles[0].getBytes());
fileUrl = "http://127.0.0.1:8080" + relativePath + File.separator + newFileName;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (fileUrl == null) {
result.put("message", "图片上传失败!");
return result;
}
result.put("message", "上传成功!");
result.put("url", fileUrl);
return result;
}
}
测试
1、启动springboot项目,用postman上传一个文件,进行上传测试
点击Send发送:上传支持:".jpg", ".jpeg", ".png",".docx",".xlsx"
上传成功后返回的结果:
具体上传文件:代码中根据File对象中真实Path进行创建一个系统时间文件下,不存在进行创建,最终展示:
下载具体实现
package com.cn.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
@RestController
public class TestDownload {
@RequestMapping("/download")
public static void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {
File f = new File(filePath);
if (!f.exists()) {
response.sendError(404, "File not found!");
return;
}
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[1024];
int len = 0;
response.reset(); // 非常重要
if (isOnLine) { // 在线打开方式
URL u = new URL("file:///" + filePath);
response.setContentType(u.openConnection().getContentType());
response.setHeader("Content-Disposition", "inline; filename=" + f.getName());
// 文件名应该编码成UTF-8
} else { // 纯下载方式
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());
}
OutputStream out = response.getOutputStream();
while ((len = br.read(buf)) > 0)
out.write(buf, 0, len);
br.close();
out.close();
}
}
测试
1、启动springboot项目,用postman下载一个文件,进行下载测试
选择参数为:filePath ,选好文件真实路径。如图:
点击Send发送:
上传成功后,返回如下的文件二进制流,如下