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";
    }

测试

image

测试成功!

posted @ 2021-04-29 18:12  1LDK  阅读(573)  评论(2编辑  收藏  举报