SpringBoot上传下载文件及在线预览

今天大概就说说如何使用SpringBoot进行上传和下载以及在线预览文件
本篇主要介绍上传下载的功能,对于界面就简单一点,大致如下:

一、老规矩还是先看看小项目的目录结构:


二、添加对应的pom依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version></dependency>

三、创建相应的配置

spring.application.name=files
server.port=8080
server.servlet.context-path=/filesspring.thymeleaf.cache=false
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.prefix=classpath:/templates/
spring.resources.static-locations=classpath:/templates/,classpath:/static/,file:${upload.dir}spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/files?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=rootmybatis.mapper-locations=classpath:/com/baizhi/mapper/*.xml
mybatis.type-aliases-package=com.baizhi.entity#控制台进行打印日志
logging.level.root=info
logging.level.com.baizhi.dao=debug#上传和下载文件的路径
upload.dir=D:/idea_project/java/files/target/classes/static

四、先准备登陆界面的工作

1、创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain=true)
public class User {private Integer id;private String username;private String password;}

2、创建对应的dao层

public interface UserDAO {User login(User user);
}

3、创建对应的mapper映射文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserDAO"><!--login--><select id="login" parameterType="User" resultType="com.baizhi.entity.User">select id,username,passwordfrom t_userwhere username=#{username}and password = #{password}</select></mapper>

4、创建业务层接口及实现类

public interface UserService {User login(User user);
}
@Service
@Transactional
public class UserServciceImpl  implements  UserService{@Autowiredprivate UserDAO userDAO;@Override@Transactional(propagation = Propagation.SUPPORTS)public User login(User user) {return userDAO.login(user);}
}

5、创建控制器

@Controller
@RequestMapping("user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;/*** 登录方法*/@PostMapping("login")public String login(User user, HttpSession session){User userDB = userService.login(user);if(userDB!=null){session.setAttribute("user",userDB);return "redirect:/file/showAll";}else{return "redirect:/index";}}}

6、创建登陆界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户登录</title>
</head>
<body><h1>欢迎访问用户文件管理系统</h1><form th:action="@{/user/login}" method="post">username: <input type="text" name="username"/> <br>password: <input type="text" name="password"/> <br><input type="submit" value="登录">
</form></body>
</html>

7、查看运行后对应的界面

五、进行主界面的操作

1、创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain=true)
public class UserFile {private Integer id;private String oldFileName;private String newFileName;private String ext;private String path;private String size;private String type;private String isImg;private Integer downcounts;private Date uploadTime;private Integer userId; //用户外键
}

2、创建对应的dao层

public interface UserFileDAO {//根据登录用户id获取用户的文件列表List<UserFile> findByUserId(Integer id);//保存用户的文件记录void save(UserFile userFile);//根据文件id获取文件信息UserFile findById(String id);//根据id更新下载次数void update(UserFile userFile);//根据id删除记录void delete(String id);
}

3、创建dao层对应的mapper映射文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserFileDAO"><!--根据用户id查询当前用户的文件信息--><select id="findByUserId" parameterType="Integer" resultType="com.baizhi.entity.UserFile">select  id,oldFileName,newFileName,ext,path,size,type,isImg,downcounts,uploadTime,userIdfrom t_fileswhere userId=#{id}</select><!--保存文件信息--><insert id="save" parameterType="com.baizhi.entity.UserFile" useGeneratedKeys="true" keyProperty="id">insert into t_filesvalues (#{id},#{oldFileName},#{newFileName},#{ext},  #{path},#{size},#{type},#{isImg},#{downcounts}, #{uploadTime},#{userId})</insert><!--根据id获取文件信息--><select id="findById" parameterType="String" resultType="com.baizhi.entity.UserFile">select id,oldFileName,newFileName,ext,path,size,type,isImg,downcounts,uploadTime,userIdfrom t_fileswhere id = #{id}</select><!--更新下载次数--><update id="update" parameterType="com.baizhi.entity.UserFile" >update t_files set downcounts=#{downcounts} where id=#{id}</update><!--根据id删除记录--><delete id="delete" parameterType="String">delete from t_files where id=#{id}</delete></mapper>

4、创建对应的业务层接口及实现类

public interface UserFileService {List<UserFile> findByUserId(Integer id);void save(UserFile userFile);UserFile findById(String id);void update(UserFile userFile);void delete(String id);
}
@Service
@Transactional
public class UserFileServiceImpl implements  UserFileService {@Autowiredprivate UserFileDAO userFileDAO;@Overridepublic List<UserFile> findByUserId(Integer id) {return userFileDAO.findByUserId(id);}@Overridepublic void delete(String id) {userFileDAO.delete(id);}@Overridepublic void update(UserFile userFile) {userFileDAO.update(userFile);}@Overridepublic UserFile findById(String id) {return userFileDAO.findById(id);}@Overridepublic void save(UserFile userFile) {//userFile.setIsImg()?  //是否是图片 解决方案: 当类型中含有image时说明当前类型一定为图片类型String isImg = userFile.getType().startsWith("image")?"是":"否";userFile.setIsImg(isImg);userFile.setDowncounts(0);userFile.setUploadTime(new Date());userFileDAO.save(userFile);}
}

5、创建控制器(重点)

  1. 上传文件(且保存到i数据库中)
@PostMapping("upload")public String upload(MultipartFile aaa, HttpSession session) throws IOException {//获取上传文件用户idUser user = (User) session.getAttribute("user");//获取文件原始名称String oldFileName = aaa.getOriginalFilename();//获取文件后缀String extension = "." + FilenameUtils.getExtension(aaa.getOriginalFilename());//生成新的文件名称String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + UUID.randomUUID().toString().replace("-", "") + extension;//文件大小Long size = aaa.getSize();//文件类型String type = aaa.getContentType();//处理根据日期生成目录//String realPath = ResourceUtils.getURL("classpath:").getPath() + "/static/files";String dateFormat = new SimpleDateFormat("yyyy-MM-dd").format(new Date());String dateDirPath = uploadPath + "/files/" + dateFormat;File dateDir = new File(dateDirPath);if (!dateDir.exists()) dateDir.mkdirs();//处理文件上传aaa.transferTo(new File(dateDir, newFileName));//将文件信息放入数据库保存UserFile userFile = new UserFile();userFile.setOldFileName(oldFileName).setNewFileName(newFileName).setExt(extension).setSize(String.valueOf(size)).setType(type).setPath("/files/" + dateFormat).setUserId(user.getId());userFileService.save(userFile);return "redirect:/file/showAll";}
  1. 下载文件(在线预览)
@GetMapping("download")public void download(String openStyle, String id, HttpServletResponse response) throws IOException {//获取打开方式openStyle = openStyle == null ? "attachment" : openStyle;//获取文件信息UserFile userFile = userFileService.findById(id);//点击下载链接更新下载次数if ("attachment".equals(openStyle)) {userFile.setDowncounts(userFile.getDowncounts() + 1);userFileService.update(userFile);}//根据文件信息中文件名字 和 文件存储路径获取文件输入流String realpath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userFile.getPath();//获取文件输入流FileInputStream is = new FileInputStream(new File(realpath, userFile.getNewFileName()));//附件下载response.setHeader("content-disposition", openStyle + ";fileName=" + URLEncoder.encode(userFile.getOldFileName(), "UTF-8"));//获取响应输出流ServletOutputStream os = response.getOutputStream();//文件拷贝IOUtils.copy(is, os);IOUtils.closeQuietly(is);IOUtils.closeQuietly(os);}
  1. 展示所有文件信息
@GetMapping("showAll")public String findAll(HttpSession session, Model model) {//在登录的session中获取用户的idUser user = (User) session.getAttribute("user");//根据用户id查询有的文件信息List<UserFile> userFiles = userFileService.findByUserId(user.getId());//存入作用域中model.addAttribute("files", userFiles);return "showAll";}
  1. 删除文件(及数据库中的)
@GetMapping("delete")public String delete(String id) throws FileNotFoundException {//根据id查询信息UserFile userFile = userFileService.findById(id);//删除文件String realPath = ResourceUtils.getURL("classpath:").getPath() + "/static" + userFile.getPath();File file = new File(realPath, userFile.getNewFileName());if(file.exists())file.delete();//立即删除//删除数据库中记录userFileService.delete(id);return "redirect:/file/showAll";}
  1. 返回当前的文件列表(json格式数据)
@GetMapping("findAllJSON")@ResponseBodypublic List<UserFile> findAllJSON(HttpSession session, Model model) {//在登录的session中获取用户的idUser user = (User) session.getAttribute("user");//根据用户id查询有的文件信息List<UserFile> userFiles = userFileService.findByUserId(user.getId());return userFiles;}

6、创建对应的界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户文件列表页面</title><script th:src="@{/js/jquery-3.4.1.min.js}"></script><script>$(function(){var time;$("#start").click(function(){console.log("开启定时更新.........");time = setInterval(function () {$.get("[[@{/file/findAllJSON}]]", function (res) {//遍历$.each(res, function (index, file) {$("#" + file.id).text(file.downcounts);})});}, 3000);});$("#stop").click(function () {console.log("关闭定时更新");clearInterval(time);});});</script>
</head>
<body><h1>欢迎: <span th:if="${session.user!=null}" th:text="${session.user.username}"/></h1>
<h3>文件列表:</h3>
<button id="start">开启定时更新</button>
<button id="stop">结束定时更新</button>
<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><th>操作</th></tr><tr th:each="file,fileStat:${files}"><td><span th:text="${file.id}"/></td><td><span th:text="${file.oldFileName}"/></td><td><span th:text="${file.newFileName}"/></td><td><span th:text="${file.ext}"/></td><td><span th:text="${file.path}"/></td><td><span th:text="${file.size}"/></td><td><span th:text="${file.type}"/></td><td><img th:if="${file.isImg}=='是'" style="width: 100px;height: 40px;" th:src="${#servletContext.contextPath}+${file.path}+'/'+${file.newFileName}" alt=""><span th:if="${file.isImg}!='是'" th:text="${file.isImg}"/></td><td th:id="${file.id}"><span th:text="${file.downcounts}"/></td><td><span th:text="${#dates.format(file.uploadTime,'yyyy-MM-dd HH:mm:ss')}"/></td><td><a th:href="@{/file/download(id=${file.id})}">下载</a><a th:href="@{/file/download(id=${file.id},openStyle='inline')}">在线打开</a><a th:href="@{/file/delete(id=${file.id})}">删除</a></td></tr>
</table>
<hr><h3>上传文件:</h3><form th:action="@{/file/upload}" method="post" enctype="multipart/form-data"><input type="file" name="aaa"> <input type="submit" value="上传文件">
</form></body>
</html>

六、创建拦截器

public class LoginInterceptor  implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();Object user = session.getAttribute("user");if(user!=null) return true;response.sendRedirect(request.getContextPath()+"/index");return false;}
}

七、创建过滤器

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {@Value("${upload.dir}")private String upload;@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/file/**").excludePathPatterns("/css/**").excludePathPatterns("/js/**");//放行静态资源 静态资源被认为是一个控制器请求}@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**") //代表以什么样的请求路径访问静态资源.addResourceLocations("classpath:/static/").addResourceLocations("classpath:/templates/").addResourceLocations("file:"+upload);//本地资源路径必须放在最上面}
}

八、进行测试

  1. 初始化

  2. 上传后

  3. 下载

  4. 在线预览

  5. 删除
    变为初始化的样子
    有需要源码的可以联系我!

还是要说说我的个人博客,希望大家多多访问,谢谢!

天涯志

SpringBoot上传下载文件及在线预览相关推荐

  1. java 上传文件及预览_SpringBoot上传下载文件及在线预览

    SpringBoot上传下载文件及在线预览 今天大概就说说如何使用SpringBoot进行上传和下载以及在线预览文件 本篇主要介绍上传下载的功能,对于界面就简单一点,大致如下: 一.老规矩还是先看看小 ...

  2. springboot上传下载文件(4)--上传下载工具类(已封装)

    因为在做毕设,发现之前的搭建ftp文件服务器,通过ftp协议无法操作虚拟机临时文件,又因为ftp文件服务器搭建的比较麻烦:而 hadoop的HDFS虽然可以实现,但我这里用不到那么复杂的:所以我封装了 ...

  3. js下载文件和在线预览文件

    // 在线预览文件let file = url;let lastIndex=file.lastIndexOf(".");let suffix=file.substring(last ...

  4. Vue - 本地上传 Excel 文件页面表格预览(配合 ElementUI / 带分页)

    文章底部,获取示例源代码,克隆仓库运行起来. 代码干净整洁,无任何冗余代码, 根据自己的需求,进行改造即可. 效果图

  5. java 预览zip_java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载

    java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载 实现功能:zip文件上传,后台自动解压,Jstree树目录(遍历文件),editor.md预览 采用Spring+Sp ...

  6. java 百度网盘上传_使用pcs api往免费的百度网盘上传下载文件的方法

    百度个人云盘空间大,完全免费,而且提供了pcs api供调用操作文件,在平时的项目里往里面保存一些文件是很实用的. 环境准备: 开通读写网盘的权限及获取access_token:http://blog ...

  7. ftp上传-下载文件通用工具类,已实测

    话不多说直接上代码 package com.springboot.demo.utils;import lombok.extern.slf4j.Slf4j; import org.apache.comm ...

  8. 初级版python登录验证,上传下载文件加MD5文件校验

    服务器端程序 import socket import json import struct import hashlib import osdef md5_code(usr, pwd):ret = ...

  9. SecureCRT上传下载文件

    2019独角兽企业重金招聘Python工程师标准>>> SecureCRT是一个仿真终端连接工具.它可以方便的连接SSH服务器,远程管理Linux.同时,它还能使用多种协议方便的上传 ...

最新文章

  1. 8个问题全面了解5G关键技术Massive MIMO
  2. JavaWeb学习总结(五十三)——Web应用中使用JavaMail发送邮件
  3. 接口interface修饰符相关问题总结
  4. 玩转 HMS Core 6.0,详解开发者该知道的黑科技……
  5. 宏定义处理特殊字符 -_c语言编译与预处理命令
  6. 公众号内打开提示404_200元500元/篇 | 她家小酒馆儿公众号征稿!(三天内审核、有额外稿费)...
  7. Mysql5.7+ 出现Field * doesn‘t have a default value解决办法
  8. OTA时代来了!由新一代私有云揭开序幕
  9. HFSS学习笔记—18.SMA模拟端口
  10. 怎么在Chrome浏览器中插入IDM软件的扩展插件?
  11. 华三s5000配置镜像接口_华为S5300交换机配置基于接口的本地端口镜像
  12. secure IRS aided ISAC
  13. c语言 go to 用法,c语言中 go to语句的使用方法
  14. Python3,多线程爬取某瓣小电影~ ~
  15. windows保护无法启动修复服务器,命令修复Win10系统提示Windows 资源保护无法启动修复服务的解决方法...
  16. 震惊!!!年度双生武魂诞生现场----双统安装(centos与windows)
  17. 我跟Python的孽缘
  18. 学习TypeScrip2(任意类型)
  19. WPF DataGrid 获取选中 一行 或者 多行
  20. Haproxy+Keepalived+MySQL高可用均衡负载部署

热门文章

  1. prettyPhoto
  2. python写的有道翻译代码_Python爬虫10行代码实现调用有道翻译,以及加入语音功能...
  3. 网络学习笔记:TCP/IP连网和Internet
  4. 一个员工的离职成本到底有多大
  5. 《Real-Time Rendering 4th Edition》全文翻译 - 第3章 图形处理单元(GPU)(下)3.7 ~ 3.10
  6. Atmel将推物联网创新解决方案
  7. 欢乐5+1选色球C语言例题:
  8. python爬取电影天堂的下载链接
  9. 横河变送器EJA110E
  10. 防止芯片管脚短接-阻焊桥与绿油开窗大小的折中