0
点赞
收藏
分享

微信扫一扫

基于SpringBoot实现文件的上传、下载和在线预览(SpringBootDemo)

嚯霍嚯 2022-01-09 阅读 44

在java领域中SpringBoot是一个非常好用的框架,可以快速地构建web项目,这里记录一下使用SpringBoot来实现文件的上传、下载和在线预览功能。

1.创建数据库和数据库表

本文主要用到用户和用户所属的文件,所以这里就只需要设计用户表和文件表即可。

用户表t_user

CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(80) DEFAULT NULL,
`password` varchar(80) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

insert into t_user(username, password) values("pikacho", "123456");

文件表t_files

CREATE TABLE `t_files` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`file_name` varchar(200) DEFAULT NULL,
`ext` varchar(20) DEFAULT NULL,
`path` varchar(300) DEFAULT NULL,
`size` bigint(64) DEFAULT NULL,
`type` varchar(120) DEFAULT NULL,
`download_counts` int(6) DEFAULT NULL,
`upload_time` datetime DEFAULT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `t_files_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

2.创建SpringBoot项目

这里不用多说,使用IDEA创建SpringBoot项目,删除多余没用的文件,让项目结构保持简洁。

 简单地创建一个控制器,然后启动项目,测试该SpringBoot项目是否构建成功。

@Controller
public class HelloController {

@RequestMapping("hello")
@ResponseBody
public String hello(){
return "hello SpringBoot";
}
}
 

访问项目:http://localhost:8080/hello,出现如下画面说明项目能够成功运行;先保证项目能成功运行,然后再考虑开发功能。

3.添加该项目需要的依赖以及配置基本环境

pom.xml依赖

       <dependencies>
<!-- thymeleaf模板引擎的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<!-- SpringBoot的web项目依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- lombok依赖,作用是创建实体类时不用自己手动添加构造器,setter等方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>

<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>

<!-- 文件上传依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

<!-- druid数据库连接池依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

application.yml主配置文件

spring:
application:
name: fileStorage
thymeleaf:
cache: false
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/fileservice?serverTimezone=Asia/Shanghai&userUnicode=true&characterEncoding=utf-8
username: root
password: root

server:
port: 8080


mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.pikacho.entity

添加完依赖以及将主配置文件配置完成,完成本项目功能需要的基本环境就已经全部搭建完成了,启动项目测试项目是否可以正常运行;出现下面的画面说明项目基本环境搭建成功。

4.用户登录、注销及注册功能

4.1.完成登录功能

即使一个非常简单的demo项目,也是少不了前端页面。对于一个后端开发者来说,要自己去写前端页面布局和样式是一件挺痛苦也困难的事(是真的不会写啊!)。所以这里使用layui框架来快速构建前端页面。当然,这只是简单的使用一下该框架,想要熟练使用。还需继续深入学习才行。

1.引入layui

将layui需要的文件添加到static文件夹下

 2.创建登录页面

login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>login</title>
<link rel="stylesheet" th:href="@{/css/layui.css}">
</head>
<body>

<div class="layui-container">
<div class="layui-row" style="margin-top: 80px;">
<div class="layui-col-lg4 layui-col-lg-offset4">
<h1 style="margin:20px; text-align: center"> 请 登 录 </h1>
<form class="layui-form" th:action="@{/user/login}" , method="post">
<div class="layui-form-item">
<p style="color: red; text-align: center" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="username" required autocomplete="false">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密 码</label>
<div class="layui-input-block">
<input class="layui-input" type="password" name="password" required autocomplete="false">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">立即登录</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<div style="float:right">
<a th:href="@{/user/toRegister}">去注册</a>
</div>
</div>
</div>
</div>

<script th:src="@{/layui.js}"></script>
<script>
//一般直接写在一个js文件中
layui.use(['layer', 'form'], function(){
var layer = layui.layer
,form = layui.form;
});
</script>
</body>
</html>

UserController.java

    /**
* 前往登录页面
* @return
*/

@RequestMapping("toLogin")
public String toLogin(){
return "login";
}

这样,之后我们就可以轻松地创建前端页面了,并且不用自己去设计样式和布局等问题。还是要提一下,像这样简单使用一下这种程度就够了,但是要熟练使用的话,就要更加深入学习才行。

3.完成登录功能

  • 创建User实体类--User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {

private Integer id;
private String username;
private String password;
}
  • 创建UserDao及其mapper映射文件--UserDao.java & UserDaoMapper.xml

@Mapper
@Repository
public interface UserDao {

/**
* 用户登录功能
* @return
*/

public User login(User user);


}
<?xml version = '1.0' encoding = 'UTF-8' ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.pikacho.dao.UserDao">
<!-- public User login(User user)-->
<select id="login" parameterType="User" resultType="User">
select id, username, password
from t_user
where username = #{username} and password = #{password};
</select>

  • 创建UserService类及其实现类--UserService.java & UserServiceImpl.java

public interface UserService {
public User login(User user);
}
@Service
public class UserServiceImpl implements UserService {

@Autowired
public UserDao userDao;

@Override
public User login(User user){
return userDao.login(user);
}
}
  • 利用Shiro框架实现登录认证功能

Shiro框架可以快速实现登录认证等安全权限功能,这里也是简单使用一下,想要深入理解使用还需查阅其官方文档。

UserRealm.java

public class UserRealm extends AuthorizingRealm {

@Autowired
private UserService userService;


// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){
return null;
}

// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;

User user = new User();
user.setUsername(usernamePasswordToken.getUsername());
user.setPassword(String.valueOf(usernamePasswordToken.getPassword()));
// 从数据库查询出来
User userDB = userService.login(user);
if(userDB == null){
return null;
}

return new SimpleAuthenticationInfo(userDB, user.getPassword(), "");

}
}

ShiroConfig.java

@Configuration
public class ShiroConfig {

// 第一步:创建UserRealm对象
@Bean
public UserRealm userRealm(){
return new UserRealm();
}

// 第二步:创建默认安全管理器DefaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(
@Qualifier("userRealm") UserRealm userRealm )
{
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}

// 第三步:创建ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(
@Qualifier("securityManager") DefaultWebSecurityManager securityManager)
{
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
// 设置安全管理器
bean.setSecurityManager(securityManager);
/*
* anon: 无需认证就能访问
authc: 必须认证后才能访问
user: 必须拥有 记住我 功能才能用
perms: 拥有对某个资源的权限才能访问
role: 拥有某个角色权限才能访问
*/


// 拦截/file/* ,该路径只有登录的情况下才能查看
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/file/*", "authc");
bean.setFilterChainDefinitionMap(filterMap);

// 设置没有访问权限时,跳转页面
bean.setLoginUrl("/login");
return bean;
}
}
  • 在UserController类中添加登录方法
    @PostMapping("login")
public String login(User user, Model model){
Subject subject = SecurityUtils.getSubject();
// 封装用户信息
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
try{
subject.login(token);
Session session = subject.getSession();
session.setAttribute("user", (User)subject.getPrincipal());
// 前往文件列表页面
return "list";
}catch (UnknownAccountException e){
model.addAttribute("msg", "用户名或密码错误");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg", "用户名或密码错误");
return "login";
}
}
  • 最后在SpringbootFileuploadApplication类上添加包扫描注解,不然mybatis无法将接口和xml配置文件绑定起来
@SpringBootApplication
@MapperScan(basePackages = "com.pikacho.dao")
public class SpringbootFileuploadApplication {

public static void main(String[] args) {
SpringApplication.run(SpringbootFileuploadApplication.class, args);
}

}

登录功能代码已经开发完毕了,现在测试一下功能是否正常。 

访问项目:http://localhost:8080/user/toLogin,之前创建用户表时,就已经创建了一个用户。用户名:pikacho  密码:123456。

 

 4.2.完成注册功能

1.创建注册页面

register.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>register</title>
<link rel="stylesheet" th:href="@{/css/layui.css}">

</head>
<body>
<div class="layui-container">
<div class="layui-row" style="margin-top: 80px;">
<div class="layui-col-lg4 layui-col-lg-offset4">
<h1 style="margin:20px; text-align: center"> 请 注 册 </h1>
<div class="layui-form-item">
<p style="color: red; text-align: center" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
</div>
<form class="layui-form" th:action="@{/user/register}" method="post">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="username" required>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密 码</label>
<div class="layui-input-block">
<input class="layui-input" type="password" name="password" required autocomplete="false">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">立即注册</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<div style="float:right">
<a th:href="@{/user/toLogin}">去登录</a>
</div>
</div>
</div>
</div>
<script th:src="@{/layui.js}"></script>
<script>
//一般直接写在一个js文件中
layui.use(['layer', 'form'], function(){
var layer = layui.layer
,form = layui.form;
});

</script>



</body>
</html>

2.完成注册功能

  • 在UserDao类中添加register(),编写mapper映射文件
    /**
*
* @param user
*/

public void register(User user);
    <!-- 注册-->
<insert id="register" parameterType="User">
insert into t_user (username, password)
values(#{username}, #{password});
</insert>
  • 在UserService类及实现类中添加注册方法
    /**
*
* @param user
*/

public void register(User user);
    /**
*
* @param user
*/

@Override
public void register(User user){
userDao.register(user);
}
  • 在UserController类中添加注册逻辑

测试注册功能, 访问项目:http://localhost:8080/user/toRegister ;添加用户pikacho2 :123456

 

 

4.3.创建list页面

前面只是简单的创建一个list页面验证登录功能,现在补全list页面。

list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>FileList</title>
<link rel="stylesheet" th:href="@{/css/layui.css}">
</head>

<body>
<div class="layui-fluid">
<nav class="layui-nav">
<div class="layui-nav-item">
<p class="layui-nav-title" style="font-size: larger">
欢迎:<span th:if="${session.user!=null}" th:text="${session.user.username}"/>
</p>
</div>
<div class="layui-nav-item" style="float: right;">
<button class="layui-btn">
<a th:href="@{/user/logout}" style="font-size: larger; padding: 0px; color: white">login out</a>
</button>
</div>
<div class="layui-nav-item" style="float: right; padding-right: 20px">
<button type="button" class="layui-btn" id="fileUpload">
上传文件
</button>
</div>
</nav>

<!-- 文件列表-->
<table id="fileList" lay-filter="fileTable"></table>

<script type="text/html" id="optBar">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="download">下载</a>
<a class="layui-btn layui-btn-xs" lay-event="preview">预览</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
</script>

</div>
<script th:src="@{/layui.js}" charset="utf-8"></script>

</body>
</html>

 4.4.完成注销功能

  • 在UserController类中添加注销方法
    /**
* 注册功能
* @return
*/

@GetMapping("logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
// 这里需要注意:redirect:user/toLogin 实际的请求路径http://localhost:8080/user/user/toLogin
// 所以需要使用redirect:toLogin
return "redirect:toLogin";
}

5.文件的展示、上传、删除、下载功能

5.1.文件的展示

  • 创建文件实例类--UserFile.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Accessors(chain = true)
public class UserFile {
private Integer id;
private String fileName;
private String ext;
private String path;
private long size;
private String type;
private Integer downloadCounts;
private Date uploadTime;
private Integer userId;
}
  • 创建UserFileDao及其mapper映射文件
@Mapper
@Repository
public interface UserFileDao {

/**
* 根据用户id获得用户文件列表
* @param id
* @param begin
* @param offset
* @return
*/

public List<UserFile> queryByUserId(Integer id, Integer begin, int offset);


/**
* 根据用户id获得该用户文件总数
* @param id
* @return
*/

public int queryFileCount(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.pikacho.dao.UserFileDao">
<resultMap id="UserFileMap" type="UserFile">
<!-- 只需要映射列名和属性名不一致的-->
<id column="id" property="id"></id>
<result column="file_name" property="fileName"></result>
<result column="download_counts" property="downloadCounts"></result>
<result column="upload_time" property="uploadTime"></result>
<result column="user_id" property="userId"></result>
</resultMap>

<!-- 根据用户id查询文件列表-->
<select id="queryByUserId" parameterType="Integer" resultMap="UserFileMap">
select * from t_files
where user_id = #{id}
order by id
limit #{begin}, #{offset};
</select>
<!-- 根据用户id查询文件数量-->
<select id="queryFileCount" parameterType="Integer" resultType="Integer">
select count(*) from t_files
where user_id = #{id};
</select>
</mapper>
  • 创建UserFileService类及其实现类
public interface UserFileService {

/**
* 根据用户id获得文件列表
* @param id
* @param page
* @param limit
* @return
*/

public List<UserFile> queryByUserId(Integer id, Integer page, Integer limit);

/**
* 根据用户id获得文件数
* @param id
* @return
*/

public int queryFileCounts(Integer id);
}
@Service
public class UserFileServiceImpl implements UserFileService {
@Autowired
private UserFileDao userFileDao;

/**
* 根据用户id获得文件列表
* @param id
* @param page
* @param limit
* @return
*/

@Override
public List<UserFile> queryByUserId(Integer id, Integer page, Integer limit){
// page表示第几页,limit表示每页显示多少行数据
int begin = (page-1)*limit; // 该计算方法获得开始的位置
int offset = limit;
return userFileDao.queryByUserId(id, begin, limit);
}

/**
* 根据用户id获得文件数
* @param id
* @return
*/

@Override
public int queryFileCounts(Integer id){
return userFileDao.queryFileCounts(id);
}
}
  • 创建UserFileController类
@Controller
@RequestMapping("file")
public class UserFileController {
@Autowired
private UserFileService userFileService;

/**
* 返回文件列表
* @param session
* @param request
* @return
*/

@PostMapping("all")
@ResponseBody
public Map<String, Object> queryAllFile(HttpSession session, HttpServletRequest request){
int page = Integer.parseInt(request.getParameter("page"));
int limit = Integer.parseInt(request.getParameter("limit"));
User user = (User) session.getAttribute("user");
List<UserFile> files = userFileService.queryByUserId(user.getId(), page, limit);

Map<String, Object> res = new HashMap<>();
res.put("code", 0);
res.put("count", userFileService.queryFileCounts(user.getId()));
res.put("data", files);
return res;
}

}
  • 接着在list.html中添加渲染表格的脚本
        // 渲染表格
table.render({
elem: '#fileList',
height: 600,
minWidth: 80,
url: '/file/all', // 这一定要是/file/all,之前我是file/all不停的报错,无法访问成功
parseData: function (res) {
return {
"code": res.code,
"msg": "",
"count": res.count,
"data": res.data
};
},
method: 'post',
limit: 10,
page: true,
cols: [[
{field:'id', title:'ID', sort:true, fixed:'left'},
{field:'fileName', title:'文件名'},
{field:'ext', title:'文件后缀'},
{field:'path', title:"存储路径"},
{field:'size', title:'大小'},
{field:'type', title:"类型"},
{field:'downloadCounts', title:'下载次数'},
{field:'uploadTime', title:'上传时间'},
{tilte:'操作',align:'center', toolbar:'optBar', width:200, fixed:'right'}
]]
});

5.2.文件上传

  • 在UserFileDao类中添加上传文件方法及mapper映射文件
    /**
* 上传文件
* @param userFile
*/

public void save(UserFile userFile);
    <!-- 上传文件-->
<insert id="save" parameterType="UserFile" useGeneratedKeys="true" keyProperty="id">
insert into t_files(file_name, ext, path, size, type, download_counts, upload_time, user_id)
values(#{fileName}, #{ext}, #{path}, #{size}, #{type}, #{downloadCounts}, #{uploadTime}, #{userId});
</insert>
  • 在UserFileService类及UserFileServiceImpl类中添加方法
    /**
* 上传文件
* @param userFile
*/

public void save(UserFile userFile);



/**
* 上传文件
* @param userFile
*/

@Override
public void save(UserFile userFile){
userFile.setDownloadCounts(0).setUploadTime(new Date());
userFileDao.save(userFile);
}
  • 在UserFileController类中添加上传文件接口
    @GetMapping("index")
public String fileIndex(){
return "list";
}


/**
* 上传文件
* @param file
* @param session
* @return
*/

@PostMapping("upload")
@ResponseBody
public Map<String, String> uploadFile(@RequestParam("file")MultipartFile file, HttpSession session){
Map<String, String> res = new HashMap<>();
try{
User user = (User) session.getAttribute("user");
String fileName = file.getOriginalFilename();
String extension = FilenameUtils.getExtension(fileName);
long size = file.getSize();
String type = file.getContentType();
// 根据日期生成目录
String localContainer = "/fileContainer";
String uploadPath = ResourceUtils.getURL("classpath").getPath()+localContainer;
String dateFormat = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
File dateDirPath = new File(uploadPath+File.separator+dateFormat);
if(!dateDirPath.exists()){
dateDirPath.mkdirs();
}

file.transferTo(new File(dateDirPath, fileName));
// 将文件信息存入数据库
UserFile userFile = new UserFile();
userFile.setFileName(fileName)
.setExt('.'+extension)
.setPath(Paths.get(localContainer, dateFormat, fileName).toString())
.setSize(size)
.setType(type)
.setUserId(user.getId());

userFileService.save(userFile);

res.put("code", "0");
res.put("msg", "上传成功");
res.put("url", "/file/index");

}catch(IOException e){
res.put("code", "-1");
res.put("msg", "上传失败");
res.put("url", "/file/index");
}
return res;
}

 

这里文件存储在我的本地磁盘上,文件表中存储的是文件在我磁盘存储的存储路径。

5.3.文件下载

开发流程与上面基本一致。

 // UserFiledao
/**
* 下载文件
* @param id
* @return
*/

public UserFile queryByUserFileId(Integer id);

/**
* 更新文件下载次数
* @param userFile
*/

public void update(UserFile userFile);


// UserFileService
/**
* 下载文件
* @param id
* @return
*/

public UserFile queryByUserFileId(Integer id);

/**
* 跟新文件下载次数
* @param userFile
*/

public void update(UserFile userFile);

// UserFileServiceImpl
/**
* 下载文件
* @param id
* @return
*/

@Override
public UserFile queryByUserFileId(Integer id) {
return userFileDao.queryByUserFileId(id);
}

/**
* 跟新文件下载次数
* @param userFile
*/

@Override
public void update(UserFile userFile) {
userFileDao.update(userFile);
}
    <!-- 下载文件-->
<select id="queryByUserFileId" parameterType="Integer" resultMap="UserFileMap">
select * from t_files where id = #{id};
</select>
<!-- 更新文件下载次数-->
<update id="update" parameterType="UserFile">
update t_files set download_counts = #{downloadCounts} where id = #{id};
</update>
    /**
* 下载文件
* @param id
* @param response
*/

@GetMapping("download/{id}")
public void download(@PathVariable("id") Integer id, HttpServletResponse response){
String openStyle = "attachment";
try{
getFile(openStyle, id, response);
}catch (Exception e){
e.printStackTrace();
}
}

/**
* 更新文件下载次数
* @param openStyle
* @param id
* @param response
* @throws Exception
*/

public void getFile(String openStyle, Integer id, HttpServletResponse response) throws Exception {
UserFile userFile = userFileService.queryByUserFileId(id);
String realPath = ResourceUtils.getURL("classpath").getPath()+userFile.getPath();

FileInputStream is = new FileInputStream(new File(realPath));
// 附件下载
response.setHeader("content-disposition", openStyle+";filename=" + URLEncoder.encode(userFile.getFileName(), "UTF-8"));
// 获取响应response输出流
ServletOutputStream os = response.getOutputStream();
// 文件拷贝
IOUtils.copy(is, os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);

if(openStyle.equals("attachment")){
userFile.setDownloadCounts(userFile.getDownloadCounts()+1);
userFileService.update(userFile);
}
}

list.html

        //监听工具条
table.on('tool(fileTable)', function (obj) {
var data = obj.data;
if (obj.event === 'download') {
window.open("/file/download/" + data.id);
obj.update({
"downloadCounts": data.downloadCounts + 1
});
} else if (obj.event === 'delete') {
layer.confirm('真的删除文件吗?', function (index) {
$.ajax({
url: "/file/delete/" + data.id,
type: "Get",
success: function (res) {
layer.msg(res.msg);
obj.del();
},
error: function (res) {
$.message.alert('msg', res.msg);
}
});
layer.close(index);
});
} else if (obj.event === 'preview') {

layer.open({
type: 2,
skin: 'layui-layer-demo', //样式类名
title: '文件预览',
closeBtn: 1, //显示关闭按钮
anim: 2,
area: ['893px', '600px'],
shadeClose: true, //开启遮罩关闭
content: '/file/preview/' + data.id
});
}
});

 5.4.文件删除

文件删除开发流程也是同上。

6.完成文件预览功能

  • 添加预览方法

    /**
* 文件预览
* @param id
* @param response
* @throws IOException
*/

@GetMapping("preview/{id}")
public void preview(@PathVariable("id") Integer id, HttpServletResponse response) throws Exception {
String openStyle = "inline";
getFile(openStyle,id,response);
}

到此,这个小项目就基本完成。

demo源码地址https://github.com/picacho-pkq/SpringBoot-demo

demo下载地址https://download.csdn.net/download/pikcacho_pkq/75146243

举报

相关推荐

0 条评论