文件上传下载

1、引入 Maven 依赖

  1. <dependency>
  2. <groupId>commons-fileupload</groupId>
  3. <artifactId>commons-fileupload</artifactId>
  4. <version>1.4</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  9. </dependency>

2、application.yml 配置

  1. server:
  2. port: 8081
  3. servlet:
  4. context-path: /files
  5. spring:
  6. application:
  7. name: files
  8. resources:
  9. static-locations: classpath:static/
  10. datasource:
  11. driver-class-name: com.mysql.cj.jdbc.Driver
  12. url: jdbc:mysql://localhost:3306/files?characterEncoding=utf8&serverTimezone=UTC
  13. username: root
  14. password: 123456
  15. type: com.alibaba.druid.pool.DruidDataSource
  16. thymeleaf:
  17. cache: false
  18. suffix: .html
  19. encoding: utf-8
  20. prefix: classpath:/templates/
  21. devtools:
  22. restart:
  23. enabled: true
  24. servlet:
  25. multipart:
  26. max-request-size: 10MB # 上传文件总的最大值
  27. max-file-size: 10MB # 单个文件的最大值
  28. mybatis:
  29. mapper-locations: classpath:mapper/*.xml
  30. type-aliases-package: com/example/entity

3、数据库

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_files
-- ----------------------------
DROP TABLE IF EXISTS `t_files`;
CREATE TABLE `t_files`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `oldFileName` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `newFileName` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `ext` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `path` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `size` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `type` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `isImg` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `downloadCounts` int(0) NULL DEFAULT NULL,
  `uploadTime` datetime(0) NULL DEFAULT NULL,
  `usserId` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `userId`(`usserId`) USING BTREE,
  CONSTRAINT `userId` FOREIGN KEY (`usserId`) REFERENCES `t_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `username` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'zhangsan', '123456');
INSERT INTO `t_user` VALUES (2, 'lisi', '123456');

SET FOREIGN_KEY_CHECKS = 1;

5、Dao、service、serviceimpl

@Accessors(chain = true)    // set、get 方法返回类型为 User
@Data
public class User {
    private Integer id;
    private String username;
    private String password;
}

6、UserMapper、UserFileDaoMapper

<?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.example.dao.UserDao">
    <!-- login -->
    <select id="Login" resultType="com.example.entity.User" parameterType="com.example.entity.User">
        select id,username,password from t_user
        where username=#{username} and password=#{password}
    </select>
</mapper>
<?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.example.dao.UserFileDao">
    <!-- login -->
    <!--    <select id="Login" resultType="com.example.entity.User" parameterType="com.example.entity.User">-->
    <!--        select id,username,password from t_user-->
    <!--        where username=#{username} and password=#{password}-->
    <!--    </select>-->
    <!--    根据用户的 id 获取当前用户的文件信息-->
    <select id="findByUserId" resultType="UserFile" parameterType="Integer">
        select * from t_files where userId=#{id}
    </select>
<!--    保存文件信息-->
    <insert id="saveFileMessage" parameterType="UserFile" useGeneratedKeys="true" keyProperty="id">
        insert into t_files (id,oldFileName,newFileName,ext,path,size,type,isImg,downloadCounts,uploadTime,userId)
        values (#{id},#{oldFileName},#{newFileName},#{ext},#{path},#{size},#{type},#{isImg},#{downloadCounts},#{uploadTime},#{userId});
    </insert>
<!-- 根据 id 获取文件信息 -->
    <select id="findById" parameterType="Integer" resultType="UserFile">
        select * from t_files where id=#{id}
    </select>
<!-- 更新下载次数 -->
    <update id="updateCount" parameterType="UserFile">
        update t_files set downloadCounts=#{downloadCounts} where id=#{id}
    </update>
  <!-- 根据 id 删除记录-->
    <delete id="delete" parameterType="Integer">
        delete from t_files where id=#{id}
    </delete>
</mapper>

7、Controller

@Controller
public class IndexController {   // 登录界面
    @GetMapping("index")
    public String toLogin(){
        return "login";
    }
}
@Controller
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 登录
     * @return
     */
    @PostMapping("login")
    public String login(User user, HttpSession session){
        User userDB = userService.Login(user);
        if(userDB != null){
            //查询成功
            session.setAttribute("user",userDB);
            return "redirect:/file/fileAll";
        }
        return "redirect:/index";
    }
}
@Controller
@RequestMapping("file")
public class FileController {
    @Autowired
    private UserFileService userFileService;
    @GetMapping("fileAll")
    public String findAll(HttpSession session, Model model){
        User user = (User) session.getAttribute("user");
        // 得到用户的所有文件信息
        List<UserFile> userFiles = userFileService.findByUserId(user.getId());
        // 存入作用域
        model.addAttribute("files",userFiles);
        return "showAll";
    }
    /**
     * 上传文件
     * @return
     */
    @PostMapping("upload")
    public String uploadFile(MultipartFile fileInformation,HttpSession session) throws IOException {
        // 获取用户的 id
        User user = (User) session.getAttribute("user");
        // 获取文件的原始名称
        String oldFileName = fileInformation.getOriginalFilename();
        // 获取文件后缀
        String file_ext = "." + FilenameUtils.getExtension(fileInformation.getOriginalFilename());
        // 生成新的文件名称
        String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+oldFileName;
        // 文件大小
        long size = fileInformation.getSize();
        // 文件类型
        String type = fileInformation.getContentType();

        // 保存文件的路径
        String upload_path = ResourceUtils.getURL("classpath:").getPath() + "static/save";
        // 创建日期文件夹
        String dateFormat = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dateDirPath = upload_path + "/" + dateFormat;
        File dateDir = new File(dateDirPath);
        if(!dateDir.exists()){
            dateDir.mkdirs();
        }
        // 处理文件上传
        fileInformation.transferTo(new File(dateDir,newFileName));
        // 将文件信息放入数据库中
        UserFile userFile = new UserFile();
        userFile.setOldFileName(oldFileName).setNewFileName(newFileName)
                .setExt(file_ext).setSize(size).setType(type)
                .setPath("save/"+dateFormat+"/"+newFileName).setUserId(user.getId());
        userFileService.saveFileMessage(userFile);

        System.out.println("success");
        return "redirect:/file/fileAll";
    }
    /**
     * 文件下载
     */
    @GetMapping("download")
    public void downloadFile(String openStyle, Integer id, HttpServletResponse response) throws IOException {
        //获取打开方式   attachment --> 文件下载   inline --> 在线打开
        openStyle = openStyle==null?"attachment":openStyle;
        // 获取文件信息
       UserFile userFile = userFileService.findById(id);
       // 获取文件路径
        String filePath = ResourceUtils.getURL("classpath:").getPath() + "static/" + userFile.getPath();
        // 获取文件输入流
        FileInputStream is = new FileInputStream(new File(filePath));
        // 附件下载
        //  attachment --> 文件下载   inline --> 在线打开
        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);
        //更新下载次数
        if("attachment".equals(openStyle)){
            userFile.setDownloadCounts(userFile.getDownloadCounts()+1);
            userFileService.updateCount(userFile);
        }
    }
    localhost:8089/hd/user/getHead?filename=head_1640009912462wallhaven-q2g75l.jpg
    /**
     * 删除文件信息
     * @param id
     * @return
     */
    @GetMapping("delete")
    public String Delete(String id) throws FileNotFoundException {
        // 根据 id 查询信息
        UserFile userFile = userFileService.findById(Integer.valueOf(id));
        // 删除文件
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/" + userFile.getPath();
        File file = new File(realPath,userFile.getNewFileName());
        if (file.exists()){
            file.delete();
        }
        // 删除数据库中的记录
        userFileService.delete(Integer.valueOf(id));
        return "redirect:/file/fileAll";
    }
}

8、login.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</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>

9、showAll.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>文件列表</title>
</head>
<body>
<h1>欢迎:<span th:if="${session.user != null}" th:text="${session.user.username}"></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>
        <th>操作</th>
    </tr>
    <tr th:each="file,fileStat:${files} ">
        <td><span th:text="${file.id}"></span></td>
        <td><span th:text="${file.oldFileName}"></span></td>
        <td><span th:text="${file.newFileName}"></span></td>
        <td><span th:text="${file.ext}"></span></td>
        <td><span th:text="${file.path}"></span></td>
        <td><span th:text="${file.size}"></span></td>
        <td><span th:text="${file.type}"></span></td>
        <td>
            <img th:if="${file.isImg}=='是'" th:src="@{/} + ${file.path}" style="width: 50px;height: 50px">
            <span th:if="${file.isImg}!='是'" th:text="${file.isImg}"></span>
        </td>
        <td><span th:text="${file.downloadCounts}"></span></td>
        <td><span th:text="${file.uploadTime}"></span></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/>
<form th:action="@{/file/upload}" method="post" enctype="multipart/form-data">
    <input type="file" name="fileInformation"/>
    <input type="submit" value="上传文件"/>
</form>
</body>
</html>