1.首先得有一个前端发请求的界面,这里我选用的是layui的文件上传组件,比较美观一点
<%@page contentType="text/html; charset=UTF-8" %>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.4.5/css/layui.css" charset="UTF-8" media="all">
</head>
<body>
<button type="button" class="layui-btn layui-btn-danger" id="test7"><i class="layui-icon"></i>上传图片</button>
<div class="layui-inline layui-word-aux">
这里以限制 10M 为例
</div>
<div class="layui-upload-list">
<img class="layui-upload-img" id="demo1" style="width: 100px;height: 100px">
<p id="demoText"></p>
</div>
<script src="https://www.layuicdn.com/layui-v2.4.5/layui.js" charset="UTF-8"></script>
<script>
layui.use('upload', function() {
var $ = layui.jquery
, upload = layui.upload;
//设定文件大小限制
upload.render({
elem: '#test7'
, url: '/upload' //改成您自己的上传接口
, size: 10240 //限制文件大小,10M 单位 KB
// , done: function (res) {
// layer.msg('上传成功');
// console.log(res)
// }
,done: function(res){
console.log(res)
//如果上传失败
if(res.code > 0){
return layer.msg('上传失败');
}
//上传成功
layer.msg('上传成功');
}
,before: function(obj){
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result){
$('#demo1').attr('src', result); //图片链接(base64)
});
}
,error: function() {
//演示失败状态,并实现重传
var demoText = $('#demoText');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
})
})
</script>
</body>
</html>
2.其次是后端的请求接收的逻辑
//上传文件存放目录
private static final String LOCATION ="D:\\ideaProjects\\ssm\\ssm2\\src\\main\\webapp\\static\\upload";
//上传逻辑
@ResponseBody
@PostMapping("/upload")
public Map<String, Object> upload(HttpServletRequest request,MultipartFile file){
Map<String,Object> message = new HashMap<>();
//1.获取原文件的后缀名
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf('.'));
//2.设置新的文件名
String newFileName = UUID.randomUUID().toString() + fileSuffix;
//3.创建新的文件
File newFile = new File(LOCATION + "\\" + newFileName);
//4.将旧文件内容复制到新文件
try {
file.transferTo(newFile);
} catch (IOException e) {
message.put("code", 1);
return message;
//e.printStackTrace();
}
message.put("code", 0);
return message;
}
3.在list.jsp页面将所有已上传的文件显示
@GetMapping("/list")
public String list(Model model){
List<String> fileNames = FileUtil.getFileNames(LOCATION);
Map<String,String> images = new HashMap<>();
for (String name:fileNames) {
images.put(name, URL + "/" + name);
}
System.out.println(images);
model.addAttribute("images", images);
return "list";
}
FileUtil.getFileNames的逻辑如下
/**
* 获取某一路经下的所有文件
* 如果含目录,则目录部分忽略
* @param dir
* @return
*/
public static List<String> getFileNames(String dir){
File file = new File(dir);
List<String> names = new ArrayList<>();
if(file.isDirectory()){
String[] list = file.list();
for (String name:list) {
File f = new File(dir + "/" + name);
if(!f.isDirectory()){
names.add(name);
}
}
}
return names;
}
4. 最后是下载的逻辑,是通过list.jsp页面点击发送请求,并传入文件名,这里由于是通过地址栏解析出来的参数,地址栏会过滤掉"."之后的东西,所以后端需要通过名字去查找一下文件。
//文件下载
@RequestMapping("/download/{fileName}")
public void download(@PathVariable(value = "fileName") String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException
{
List<String> fileNames = FileUtil.getFileNames(LOCATION);
for (String name:fileNames) {
if(name.substring(0, name.indexOf('.')).equals(fileName)){
fileName = name;
break;
}
}
File file=new File(LOCATION+"\\"+fileName);
if(file.exists()){
//设置MIME类型
response.setContentType("application/octet-stream");
//或者为response.setContentType("application/x-msdownload");
//设置头信息,设置文件下载时的默认文件名,同时解决中文名乱码问题
response.addHeader("Content-disposition", "attachment;filename="+new String(fileName.getBytes(), "ISO-8859-1"));
InputStream inputStream=new FileInputStream(file);
ServletOutputStream outputStream=response.getOutputStream();
byte[] bs=new byte[1024];
while((inputStream.read(bs)>0)){
outputStream.write(bs);
}
outputStream.close();
inputStream.close();
}
}
ending…