SpringBoot实现文件的上传和下载
SpringBoot实现文件的上传和下载
数据库,页面内容
数据库类型
CREATE TABLE `files_t` (
`id` int(12) UNSIGNED NOT NULL AUTO_INCREMENT,
`oldFileName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`newFileName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`ext` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`size` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`type` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`downCounts` int(8) NULL DEFAULT NULL,
`uploadTime` datetime(0) NULL DEFAULT NULL,
`userId` int(12) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
页面showAll.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page import="java.util.List,com.users.pojo.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>用户文件列表页面</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<h1>欢迎:<span>${sessionScope.SMSG_SESSION.st_name}</span></h1>
<h3>文件列表:</h3>
<table border="1px">
<tr>
<th>ID</th>
<th>文件原始名称</th>
<th>文件新名称</th>
<th>文件后缀</th>
<th>存储路径</th>
<th>文件大小</th>
<th>类型</th>
<th>下载次数</th>
<th>上传时间</th>
<th>操作</th>
</tr>
<c:forEach items="${fileList}" var="file">
<tr>
<td><span>${file.id}</span></td>
<td><span>${file.oldFileName}</span></td>
<td><span>${file.newFileName}</span></td>
<td><span>${file.ext}</span></td>
<td><span>${file.path}</span></td>
<td><span>${file.size}</span></td>
<td><span>${file.type}</span></td>
<td><span>${file.downCounts}</span></td>
<td><span>${file.uploadTime}</span></td>
<td>
<a href="/allLoad/download?id=${file.id}">下载</a>
<a href="/allLoad/open?id=${file.id}">在线打开</a>
<a href="/allLoad/delete?id=${file.id}">删除</a>
</td>
</tr>
</c:forEach>
</table>
<hr>
<h3>上传文件:</h3>
<form method="post" action="/allLoad/upload" enctype="multipart/form-data">
<input type="file" name="file" id="file"/>
<input type="submit" value="上传文件"/>
</form>
</body>
</html>
实体类(POJO)
package com.users.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true)
public class UserFile {
private int id;
private String oldFileName;
private String newFileName;
private String ext;
private String path;
private String size;
private String type;
private int downCounts;
private Date uploadTime;
private int userId; //用户外键
}
文件上传
DAO接口
//根据登录用户id获取用户的文件列表信息
List<UserFile> findUserById(int id);
//保存用户的文件记录
void save(UserFile userFile);
Mapper
<!--根据用户id查询当前用户文件信息-->
<select id="findUserById" parameterType="int" resultType="com.users.pojo.UserFile">
select id,oldFileName,newFileName,ext,path,size,type,downcounts,uploadTime,userId
from files_t
where userId=#{id}
</select>
<!--保存文件信息-->
<insert id="save" parameterType="com.users.pojo.UserFile" keyProperty="id">
insert into files_t values
(#{id},#{oldFileName},#{newFileName},#{ext},#{path}
,#{size},#{type},#{downCounts},#{uploadTime},#{userId})
</insert>
Service接口
List<UserFile> findUserById(int id);
void save(UserFile userFile);
ServiceImpl实现类
@Override
public List<UserFile> findUserById(int id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserFileMapper mapper = sqlSession.getMapper(UserFileMapper.class);
return mapper.findUserById(id);
}
@Override
public void save(UserFile userFile) {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserFileMapper mapper = sqlSession.getMapper(UserFileMapper.class);
//暂时预设值
userFile.setDownCounts(0);
userFile.setUploadTime(new Date());
mapper.save(userFile);
}
Controller
这里需要一个登录的信息,封装在了session里的"SMSG_SESSION"变量中。
还有文件的上传路径。
/**
* 展示所有文件信息
*/
@GetMapping("/showAll")
public String findAll(HttpSession session, Model model){
//在session中获取用户id
Student_msg smsg_session =(Student_msg) session.getAttribute("SMSG_SESSION");
int st_id = smsg_session.getSt_id();
//根据用户id查询有的文件信息
List<UserFile> userFiles = userFileServiceImpl.findUserById(st_id);
//存入作用域中
model.addAttribute("fileList",userFiles);
return "/showAll";
}
//上传文件处理,并保存文件信息到数据库中
@PostMapping("/upload")
public String upload(@RequestParam("file")MultipartFile aaa, HttpSession session) throws IOException {
//获取当前登录的学生session
Student_msg smsg_session = (Student_msg) session.getAttribute("SMSG_SESSION");
//获取文件的原始名称
String oldFileName = aaa.getOriginalFilename();
//获取文件后缀
String extension = "." + FilenameUtils.getExtension(aaa.getOriginalFilename());
//生成新的文件名称
String newFileName = UUID.randomUUID().toString().replace("-","")+extension;
//文件大小
long size = aaa.getSize();
//文件类型
String type = aaa.getContentType();
//处理文件路径
String realPath = "D:\\mybatis0921\\upload";
String dateFormat = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dateDirPath = realPath + "/" + dateFormat;
//根据日期创建文件夹
File dateDir = new File(dateDirPath);
if(!dateDir.exists()){
dateDir.mkdirs();
}
//处理文件上传
aaa.transferTo(new File(dateDirPath,newFileName));
//将文件信息放入数据库中保存
UserFile userFile = new UserFile();
userFile.setOldFileName(oldFileName).setNewFileName(newFileName).setExt(extension)
.setSize(String.valueOf(size)).setType(type).setPath(dateDirPath).setUserId(smsg_session.getSt_id());
userFileServiceImpl.save(userFile);
return "redirect:/allLoad/showAll";
}
文件下载和删除
DAO接口
//根据文件id获取文件信息
UserFile findById(String id);
//根据id更新下载次数
void update(UserFile userFile);
void delete(String id);
Mapper.xml
<!--根据id获取文件信息-->
<select id="findById" resultType="com.users.pojo.UserFile">
select id,oldFileName,newFileName,ext,path,size,type,downcounts,uploadTime,userId
from files_t
where id=#{id}
</select>
<!--更新下载次数-->
<update id="update" parameterType="com.users.pojo.UserFile">
update files_t set downCounts=#{downCounts} where id=#{id}
</update>
<!--根据id删除文件-->
<delete id="delete" parameterType="string">
delete from files_t where id=#{id}
</delete>
Service接口
UserFile findById(String id);
void update(UserFile userFile);
void delete(String id);
ServiceImpl实现类
@Override
public UserFile findById(String id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserFileMapper mapper = sqlSession.getMapper(UserFileMapper.class);
return mapper.findById(id);
}
@Override
public void update(UserFile userFile) {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserFileMapper mapper = sqlSession.getMapper(UserFileMapper.class);
mapper.update(userFile);
}
@Override
public void delete(String id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserFileMapper mapper = sqlSession.getMapper(UserFileMapper.class);
mapper.delete(id);
}
Controller
用了IO流的方式进行了文件下载。文件下载和在线打开的区别是response里的setHeader方法中的content-disposition和content-inline的区别。
//文件下载
@GetMapping("/download")
public void download(String id, HttpServletResponse response) throws IOException{
//获取文件信息
UserFile userFile = userFileServiceImpl.findById(id);
//获取文件的存储路径
String realPath = userFile.getPath()+"/";
//获取文件输入流
FileInputStream is = new FileInputStream(new File(realPath, userFile.getNewFileName()));
//附件下载
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(userFile.getOldFileName(),"UTF-8"));
System.out.println(userFile.getOldFileName());
//获取响应输出流
ServletOutputStream os = response.getOutputStream();
//更新下载次数
userFile.setDownCounts(userFile.getDownCounts()+1);
userFileServiceImpl.update(userFile);
//文件拷贝
IOUtils.copy(is,os);
//关闭输入流,输出流
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
//在线打开
@GetMapping("/open")
public void open(String id, HttpServletResponse response) throws IOException{
//获取文件信息
UserFile userFile = userFileServiceImpl.findById(id);
//获取文件的存储路径
String realPath = userFile.getPath()+"/";
//获取文件输入流
FileInputStream is = new FileInputStream(new File(realPath, userFile.getNewFileName()));
//附件下载
response.setHeader("content-inline","attachment;filename="+URLEncoder.encode(userFile.getOldFileName(),"UTF-8"));
System.out.println(userFile.getOldFileName());
//获取响应输出流
ServletOutputStream os = response.getOutputStream();
//文件拷贝
IOUtils.copy(is,os);
//关闭输入流,输出流
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
//删除文件
@GetMapping("/delete")
public String delete(String id){
//根据id查询信息
UserFile userFile = userFileServiceImpl.findById(id);
//删除文件
//1.获取文件的存储路径
String realPath = userFile.getPath()+"/";
//2.获得文件
File file = new File(realPath, userFile.getNewFileName());
//3.立即删除
if(file.exists()){
file.delete();
}
//4.删除数据库中记录
userFileServiceImpl.delete(id);
return "redirect:/allLoad/showAll";
}
测试
测试成功!