发布:2022/4/9 11:34:09作者:管理员 来源:本站 浏览次数:1231
文件上传
开发Web应用时,文件上传是常见的需求,浏览器通过表单形式将文件以流的形式传递给服务器,服务器在对上传的数据解析处理。
开发环境及代码见上一篇博客-SpringBoot整合Servlet三大组件
编写文件上传的表单页面 upload.html
<!DOCTYPE html>
// 导入Thymeleaf配置
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>动态添加文件上传列表</title>
// 导入相关CSS配置文件 login为static文件夹下的文件,见静态文件导入
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<script th:src="@{/login/js/jquery.min.js}"></script>
</head>
<body>
<div th:if="${uploadStatus}" style="color: red" th:text="${uploadStatus}">上传成功</div>
<form th:action="@{/uploadFile}" method="post" enctype="multipart/form-data">
上传文件: <input type="button" value="添加文件" onclick="add()"/>
<div id="file" style="margin-top: 10px;" th:value="文件上传区域"> </div>
<input id="submit" type="submit" value="上传"
style="display: none;margin-top: 10px;"/>
</form>
<script type="text/javascript">
// 动态添加上传按钮
function add(){
var innerdiv = "<div>";
innerdiv += "<input type='file' name='fileUpload' required='required'>" +
"<input type='button' value='删除' οnclick='remove(this)'>";
innerdiv +="</div>";
$("#file").append(innerdiv);
// 打开上传按钮
$("#submit").css("display","block");
}
// 删除当前行<div>
function remove(obj) {
$(obj).parent().remove();
if($("#file div").length ==0){
$("#submit").css("display","none");
}
}
</script>
</body>
</html>
全局配置文件配置
# Thymeleaf页面缓存设置(默认为true),开发中为方便调试应设置为false,上线稳定后保持默认true
spring.thymeleaf.cache=false
# 配置国际化文件基础名
spring.messages.basename=i18n.login
# 单个上传文件大小显示(默认1MB)
spring.servlet.multipart.max-file-size=10MB
# 总上传文件大小限制(默认为10MB)
spring.servlet.multipart.max-request-size=50MB
实现文件上传功能和处理
/*
文件管理控制类
*/
@Controller
public class FileController {
// 向文件上传页面跳转
// 处理路径为:"/toUpload的GET请求",并返回上传页面的路径
@GetMapping("/toUpload")
public String toUpload(){
return "upload";
}
//文件上传管理
// 处理"/uploadFile"的POST请求,如果文件上传成功,会将上传的文件重命名并存储在指定目录
@PostMapping("/uploadFile")
public String uploadFile(MultipartFile[] fileUpload, Model model){
//默认文件上传成功,并返回状态信息
model.addAttribute("uploadStatus","上传成功!");
for(MultipartFile file: fileUpload){
//获取文件名以及后缀名
//file.getOriginalFilename()是得到上传时的文件名
String fileName = file.getOriginalFilename();
//重新生成文件名(根据具体情况生成对应文件名)
//UUID.randomUUID():生成唯一识别码
fileName = UUID.randomUUID()+"_"+fileName;
//指定上传文件本地存储目录,不存在则需要提前创建
String dirPath = "F:/file/";
File filePath = new File(dirPath);
if(!filePath.exists()){
filePath.mkdirs();
}
try{
//将file移动到targetfile目录下
file.transferTo(new File(dirPath+fileName));
}catch (Exception e){
e.printStackTrace();
model.addAttribute("uploadStatus","上传失败:"+e.getMessage());
}
}
//携带上传状态信息回调到文件上传页面
return "upload";
}
}
测试效果即可
文件下载
下载文件能够通过IO流实现,所以多数框架并没有对文件下载进行封装处理。文件下载时设计不同浏览器的解析处理,可能会出现中文乱码的情况。
英文名文件下载
添加文件下载工具依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
定制文件下载页面download.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<div style="margin-bottom: 10px">文件下载列表:</div>
<table>
<tr>
<td>xxxxx</td>
//文件下载前需要保证文件下载目录中存在文件 xxxxx 自行存放
<td><a th:href="@{/download(filename='xxxxx')}">下载文件</a></td>
</tr>
<tr>
<td>xxxxx</td>
<td><a th:href="@{/download(filename='xxxxx')}">
下载文件</a></td>
</tr>
</table>
</body>
</html>
文件下载处理方法
// 向文件下载页面跳转
@GetMapping("/toDownload")
public String toDownload(){
return "download.html";
}
// 文件下载管理
@GetMapping("/download")
public ResponseEntity<byte[]> fileDownload(String filename){
// 指定要下载的文件根路径
String dirPath = "F:/file/";
// 创建该文件对象
File file = new File(dirPath+File.separator+filename);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
// 通知浏览器以下载方式打开
headers.setContentDispositionFormData("attachment",filename);
// 定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try{
return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
}catch (Exception e){
e.printStackTrace();
return new ResponseEntity<byte[]>(e.getMessage().getBytes(),HttpStatus.EXPECTATION_FAILED);
}
}
效果测试即可
中文名文件下载
对于上部分代码测试,如果要下载的文件为一中文名文件,中文名称会变成"_",需要进行编码乱码设置
添加处理中文编码的代码
// 向文件下载页面跳转
@GetMapping("/toDownload")
public String toDownload(){
return "download.html";
}
// 文件下载管理
@GetMapping("/download")
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request, String filename) throws Exception{
// 指定要下载的文件根路径
String dirPath = "F:/file/";
// 创建该文件对象
File file = new File(dirPath+File.separator+filename);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
// 通知浏览器以下载方式打开
filename = getFilename(request,filename);
headers.setContentDispositionFormData("attachment",filename);
// 定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try{
return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
}catch (Exception e){
e.printStackTrace();
return new ResponseEntity<byte[]>(e.getMessage().getBytes(),HttpStatus.EXPECTATION_FAILED);
}
}
private String getFilename(HttpServletRequest request,String filename) throws Exception{
// IE不同版本User-Agent中出现的关键词
String[] IEBrowserKeyWords = {"MSTE","Trident","Edge"};
// 获取请求头代理信息
String userAgent = request.getHeader("User-Agent");
for(String keyWord:IEBrowserKeyWords){
if(userAgent.contains(keyWord)){
// IE内核浏览器,统一为UTF-8编码显示,并对转换的+进行更正
return URLEncoder.encode(filename,"UTF-8").replace("+"," ");
}
}
// 火狐等其他浏览器统一为ISO-8859-1编码显示
return new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}
测试通过可以下载中文名文件不出现编码问题
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4