• Springboot文件管理 -- 实现上传下载显示删除等接口详细解析 附代码(全)


    前言

    对于该篇文章涉及的知识点可看我之前的文章:
    java知识点细节:java框架零基础从入门到精通的学习路线(超全)
    springboot知识点:springboot从入门到精通(全)

    细节知识点具体有如下:@GetMapping、@PostMapping 和 @RequestMapping详细区别附实战代码(全)

    IO流以及缓冲区输入输出基础知识:

    1. java NIO从入门到精通(全)
    2. javaSE从入门到精通的二十万字总结(二)

    以上知识点查漏补缺或者在下面正文中遇到了可对应进行学习即可

    1. 知识点补充

    文件的上传下载等借口,使用最多的两个类File以及MultipartFile类,先看源代码讲解

    1.1 File类

    关于File类可看我之前的文章:java关于File类源码的详细分析 附代码(全)

    1.2 MultipartFile类

    上传多文件主要用到这个接口:MultipartFile file
    单文件为file,多文件上传即存到数组,通过遍历一个个取出即可

    源码:

    public interface MultipartFile extends InputStreamSource {
        String getName();
    
        @Nullable
        String getOriginalFilename();
    
        @Nullable
        String getContentType();
    
        boolean isEmpty();
    
        long getSize();
    
        byte[] getBytes() throws IOException;
    
        InputStream getInputStream() throws IOException;
    
        default Resource getResource() {
            return new MultipartFileResource(this);
        }
    
        void transferTo(File dest) throws IOException, IllegalStateException;
    
        default void transferTo(Path dest) throws IOException, IllegalStateException {
            FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    该接口有多个方法属性
    大致如下:

    参数描述
    getName()文件格式
    getOriginalFilename()文件名
    getContentType文件类型
    isEmpty()文件是否为空
    getSize()文件大小

    上传一张照片的时候,输出的结果大致如下:
    在这里插入图片描述
    文件中的一些其他参数,比如上传时间、文件后缀等可自个优化

    获取文件后缀的定义可通过substring截取
    函数如下:

    fileName.substring(fileName.lastIndexOf("."));
    
    • 1

    2. 本地测试

    所谓的本地接口,也就是通过本地进行上传下载删除更改文件目录显示等接口
    加深各个函数之间的运用之后,在对应进行实战开发

    2.1 上传文件

    函数名如下:

    @RestController
    @RequestMapping("file")
    @Slf4j
    public class filecontroller2 {
    
    • 1
    • 2
    • 3
    • 4

    对于slf4j的注解可看我这两文章:(主要是打印日志的文件)

    1. java常见log日志的使用方法详细解析
    2. 出现SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“.的解决方法

    上传的接口赋值一个文件名(埋下伏笔,已经写死只能从这个文件进行上传,后续会对应进行优化):

    @Value("${file.upload.url}")
    private String uploadFilePath;
    
    • 1
    • 2

    注解的引入在配置文件中(application.properties):file.upload.url=E:/upload

    之后可以通过uuid的随机赋值文件名

    //路径 + UUID(文件名)
    String realPath = uploadFilePath + "/" + UUID.randomUUID().toString().replaceAll("-", "");
    File dest = new File(realPath);
    //判断是否存在这个目录,如果不存在就在当前路径下创建
    if (!dest.exists() && !dest.isDirectory()) {
        //创建多级文件夹
        dest.getParentFile().mkdirs();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    也可以使用当前的filename进行命名:

    File dest = new File(uploadFilePath +'/'+ fileName);
    if (!dest.getParentFile().exists()) {
        dest.getParentFile().mkdirs();
    }
    
    • 1
    • 2
    • 3
    • 4

    完整示例代码如下:

    以下为多文件上传,如果改动为单文件,只需要将其数组以及遍历去除即可

    //  http://127.0.0.1:8080/file/upload
    // 填写files的参数,问号不用带
    /*
    * 上传多个文件
    * */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String FileUpload(@RequestParam("files") MultipartFile[] files){
        //终端以json格式传输,可以使用JSONObject这个类,将其json格式打在显示上
        JSONObject object=new JSONObject();
    
        //遍历各个文件
        for(int i=0;i<files.length;i++){
            String fileName = files[i].getOriginalFilename();
    
            //判断是否存在这个目录,如果不存在就在当前路径下创建
            File dest = new File(uploadFilePath +'/'+ fileName);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
    
            try {
                //上传到服务器
                files[i].transferTo(dest);
                object.put("success","上传成功");
            } catch (Exception e) {
                object.put("fail","上传失败,重新上传");
            }
        }
    
        return object.toString();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    对应通过接口测试如下:

    测试接口可通过PostMan、ApiPost等软件,可看我这篇文章的讲解:国货之光的API管理软件 - Apipost

    在这里插入图片描述

    2.2 下载文件

    通过对应的流进行下载,之后别忘记关闭流的传输

    //http://127.0.0.1:8080/file/download?fileName=1.png
    //@GetMapping("/download")
    @RequestMapping(value = "/download",  method = RequestMethod.GET)
    public String fileDownLoad(HttpServletResponse response, @RequestParam("fileName") String fileName){
        File file = new File(uploadFilePath +'/'+ fileName);
        if(!file.exists()){
            return "下载文件不存在";
        }
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName );
    
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        ) {
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) != -1) {
                bos.write(buff, 0, len);
                bos.flush();
            }
        } catch (IOException e) {
            return "下载失败";
        }
        return "下载成功";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    处理中断输入输出流的时候的异常,加入finally比较保守
    改进代码如下:

    //http://127.0.0.1:8080/file/download?fileName=1.png
    //@GetMapping("/download")
    @RequestMapping(value = "/download",  method = RequestMethod.GET)
    public String fileDownLoad(HttpServletResponse response, @RequestParam("fileName") String fileName){
        File file = new File(uploadFilePath +'/'+ fileName);
        if(!file.exists()){
            return "下载文件不存在";
        }
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName );
    
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) != -1) {
                bos.write(buff, 0, len);
                bos.flush();
            }
            return "下载成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "下载失败";
        }finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return "输入流异常";
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return "文件流异常";
                }
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    2.3 删除文件

    可以使用FileSystemUtils的类对应进行删除

    // http://127.0.0.1:8080/file3/delete  path是路径
    // @PostMapping ("/delete")
    @RequestMapping(value = "/delete",  method = RequestMethod.POST)
    public Boolean DeletePathFile(@RequestParam("path")String path){
        return FileSystemUtils.deleteRecursively(new File(path));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过api接口测试中显示true,这是因为这个类本身返回值就是Boolean值,如果删除成功返回true
    在这里插入图片描述

    2.4 显示所有目录

    该demo在本地中只能显示该路径下(已经写死)的所有目录文件

    //  http://127.0.0.1:8080/file/getAllDirs
    /*
    * 获取当前路径下的所有目录
    * */
    @RequestMapping(value = "/getAllDirs", method = RequestMethod.POST)
    public Object getAllDirs(String filepath ) {
        Map<String, Object> map = new HashMap<>();
        try {
        	// 获取目录 主要是通过递归
            List<String> dirList = getAllDir(uploadFilePath,true);
            map.put("data", dirList);
            map.put("code", 200);
            map.put("查询目录", uploadFilePath);
            map.put("message", "查询成功");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("查询目录", "无此目录");
            map.put("message", "查询失败");
        }
        return map;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    该递归目录的算法如下:

    // 获取当前路径下的所有文件/文件夹
    public List<String> getAllDir(String directoryPath, boolean isDirectory) {
        List<String> list = new ArrayList<String>();
        // 将其String转换为file文件
        File file = new File(directoryPath);
    
        // 当前如果目录不存在,或者路径是一个文件,直接返回空列表
        // 此处的路径本身已经写死了,变成一个目录,所以不用在判断是不是文件,或者路径是不是存在
    
        // 将其文件存储在文件中放置在数组内部
        // 将其每个文件
        File[] files = file.listFiles();
    
        for (int i = 0;i< files.length; i++) {
            if (files[i].isDirectory()) {
                if (isDirectory) {
                    // 一个个对应添加到其list中,也就是绝对路径
                    list.add(files[i].getAbsolutePath());
                }
                // 递归嵌套遍历类似谷粒商城的三级分组,或者lc 中的递归算法
                list.addAll(getAllDir(files[i].getAbsolutePath(), isDirectory));
            }
        }
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.5 显示所有文件

    //  http://127.0.0.1:8080/file/getAllFiles
    /*
     * 获取当前路径下的所有文件
     * */
    @RequestMapping(value = "/getAllFiles", method = RequestMethod.GET)
    public Object getAllFiles() {
        Map<String, Object> dataMap = new HashMap<>();
        Map<String, Object> listMap = new HashMap<>();
        try {
            List<Object> list = getAllFilesmethod(uploadFilePath);
            listMap.put("list",list);
            dataMap.put("data", listMap);
            dataMap.put("code", 0);
            dataMap.put("message", "查询成功");
        } catch (Exception e) {
            e.printStackTrace();
            dataMap.put("data", "");
            dataMap.put("code", 500);
            dataMap.put("message", "查询失败");
        }
        log.info(""+dataMap);
        return dataMap;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    获取所有文件的方法:

    public  List<Object> getAllFilesmethod(String directoryPath) {
        List<Object> list = new ArrayList<Object>();
        File file1 = new File(directoryPath);
        File[] files = file1.listFiles();
        for (File file : files) {
            Map<String, String> map = new HashMap<>();
            if (file.isFile()) {
                map.put("fileName", file.getName());
                map.put("filePath", file.getAbsolutePath());
                list.add(map);
            }
        }
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果想显示文件的上传时间或者是 电脑内部文件的上传时间(通过fs自带的类可以获取)
    上传时间的方法如下:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()

    显示文件大小可以通过MultipartFile类中的ile.getSize()获取文件大小
    但是这种大小只有数字,转换为B、KB等规格
    需要增加一种判断,具体如下:

    public String transferfileSize(long fileLen) {
        DecimalFormat df = new DecimalFormat("#.00");
        DecimalFormat d = new DecimalFormat("#");
        String fileSize ;
        if (fileLength < 1024) {
            fileSize = d.format((double) fileLen) + "B";
        } else if (fileLength < 1048576) {
            fileSize = df.format((double) fileLen/ 1024) + "KB";
        } else if (fileLength < 1073741824) {
            fileSize = df.format((double) fileLen/ 1048576) + "MB";
        } else {
            fileSize = df.format((double) fileLen/ 1073741824) + "GB";
        }
        return fileSize;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.6 更改 文件/目录 名

    controller代码模块和上面大同小异,区别在于核心方法
    此处post出核心模块

    // 更改目录
    // http://127.0.0.1:8080/file/FixFileName 
    // filePath为路径,newFileName为更改的名字
    public String modifyFileName(String filePath, String newFileName) {
        File file = new File(filePath);
        // 判断原文件是否存在(防止文件名冲突)
        if (!file.exists()) { 
            return null;
        }
        // 去除前后的空格
        newFileName = newFileName.trim();
        // 文件名为空,则返回null
        if ("".equals(newFileName) || newFileName == null) 
            return null;
        String newFilePath = null;
        // 文件和文件夹直接更改名字,此处的demo为windows系统,如果要将其变换linux,需要增加判断
        newFilePath = filePath.substring(0, filePath.lastIndexOf("\\")) + "\\" + newFileName;
        try {
        	// 修改文件名,内部需要是文件类,所以将其转换
            file.renameTo(new File(newFilePath)); 
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return newFilePath;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.7 创建 文件/目录

    controller代码模块和上面大同小异,区别在于核心方法
    此处post出核心模块

    主要思想是,如果创建的这个目录或者文件存在的时候,对应在后面加上(i),通过遍历加上合适的i

    // http://127.0.0.1:8080/file/makeDirs  filePath创建绝对路径
    
    /*是否存在这个目录,创建目录
    * */
    public static boolean ismakeDirs(String path) {
        File file = new File(path);
    
    	int i = 1; // 定义全局变量,主要用来增加i
        try {
            // 如果文件夹不存在且没有这个文件 直接创建
            // 这种情况比较简单
            if (!file.exists() && !file.isDirectory()) {
                file.mkdirs();
                return true;
            }else{
            	//获取最后一个分割符的后缀名
                String name = path.substring(path.lastIndexOf("/")+1,path.length());
                while(file.exists()) {
                	// 创建文件:上级目录 + 系统分割符 + 名字 + (i)
                    file = new File(file.getParent()+ File.separator+name+"("+i+")");
                    i++;
                }
                file.mkdirs();
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3. 实战开发

    思路:将其文件通过s3,获取到上传链接以及下载链接,之后将对应的信息都放置在mongo数据库中存储(比如文件名、上传时间、上传链接、下载链接等),之后通过对应操作进行增删改查

    代码:以下代码只是提供思路(部分代码有些耦合,没有定义多一个mapper类),对接aws s3代码没post出来

    三个注意点规范:

    1. 使用云服务aws s3的文件传输(对应服务器的传输需看好规范文档)
      对接服务器这块内容使用的是微服务项目的接口(各个项目独立分离,而且每个厂商服务器对接文档就不一样),以下实战中会有所省略这部分内容
    2. 数据存储到mongo数据库,可看我这篇文章:
      云服务器下载安装mongo数据库并远程连接详细图文版本(全)
      Java关于MongoTemplate的增删改查实战代码解析(全)
    3. 前端form表单的传输规范字段值(可以获取拿到什么字段以及传输显示什么字段等)

    定义一个接口类:

    public interface FileUploadService {
    
    • 1

    以及接口实现类:

    @Slf4j
    @Service
    public class FileUploadServiceImpl implements FileUploadService {
    
    • 1
    • 2
    • 3

    3.1 上传文件

    此处的上传可以通过任意位置,上传到字节流,在上传到服务器(上面的本地测试是写死某个路径)

    ResultGeneralModel这个类,是自个封装的json格式返回结果(此处就不post出这个实体类)
    类似的可以通过上面json或者定义一个map集合封装json格式仿照下

    //todo 第一个接口为上传接口
    // http://127.0.0.1:10000/file/upload
    @RequestMapping(method = RequestMethod.POST, value =  "file/upload")
    public ResultGeneralModel<String> fileUpload(@RequestParam("file") MultipartFile file) {
    
        LinkedList<String> list = fileUploadService.httpUpload(file);
        String getUploadUrl = list.getFirst();
        String getDownloadUrl = list.getLast();
        mongoService.uploadmongo(file.getOriginalFilename(), file.getSize(), getUploadUrl, getDownloadUrl);
    
        return ResultGeneralModel.newSuccess("成功上传");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    httpUpload的核心方法如下:

    @Override
    public LinkedList<String> httpUpload(MultipartFile file) {
        String getUploadUrl;
        LinkedList<String> list = new LinkedList<>();
        SdkFileInfo sdkFileInfo = new SdkFileInfo();
        
        // 定义了一个sdkFileInfo的实体类,appid也可写死 也可通过form表单的传输引入
        // 此处post出思路引导
        int appid = sdkFileInfo.getAppid();
        
        try {
            list = uploadS3(appid, file ,sdkFileInfo);
            getUploadUrl = list.getFirst();
            if (null == getUploadUrl) {
                return null;
            }
            logger.info("file upload success");
        } catch (Exception e) {
            logger.error("file error");
        }
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    具体上传到服务器的uploadS3的函数如下:
    通过将其文件变成字节流在传输到服务器,之后获取其相关信息返回

    public LinkedList<String> uploadS3(int appId, MultipartFile file, SdkFileInfo sdkFileInfo) {
        LinkedList<String> list = new LinkedList<>();
        // 获取s3的相关信息
        S3Info info = getS3Info(appId, file);
        // 判断
        list.add(info.getUpload_url());
        logger.info(info.getUpload_url());
        if (null == info) {
            logger.error("get s3 info error, user info:" + sdkFileInfo);
            return null;
        }
        byte[] bytes;
        try {
        	// 转换为字节流
            bytes = file.getBytes();
        } catch (IOException e) {
            logger.error("read file bytes fail, user info:" + sdkFileInfo, e);
            return null;
        }
    
    	// 之后通过putUploadFile的方法进行传输,此处对应s3服务器的对接文档
    	// 转换字节流对应传输,此方法没有post出来
        if (!httpService.putUploadFile(info.getUpload_url(), bytes)) {
            logger.error("upload file error, user info:" + sdkFileInfo);
            return null;
        }
        list.add(info.getDownload_url());
        logger.info(info.getDownload_url());
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    具体获取S3的相关信息,首先需要账号密码以及字段值的配对

    private S3Info getS3Info(int appId, MultipartFile file) {
    	// 获取S3的相关信息(通过注解引入commonConfig 之后getS3Url获取url属性)
        String url = commonConfig.getS3Url();
        Map<String, String> params = new HashMap<>();
        // 对应传输进入属性
        params.put("product", "xxx");
        params.put("expire", String.valueOf(appId));
    
    	// 获取其后缀,如果有后缀则添加进入,下载链接会有后缀,直接下载文件
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
        if(suffix != null){
            params.put("suffix",suffix);
        }
    
    	// 判断url的参数结果
    	// 通过注解引入httpService
    	// 此处的代码需参考s3,同样也不post出代码
        String resultString = httpService.get(url, params);
        String dataString = httpService.httpResultCheck(url, params, resultString);
        return null != dataString ? JSON.parseObject(dataString, S3Info.class) : null;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    对应的数据库那一块的处理,通过uploadmongo函数,该函数如下:

    @Override
    public void uploadmongo(String fileName, Long fileSize, String getUploadUrl, String getDownloadUrl){
        SdkInfo sdkInfo = new SdkInfo();
        sdkInfo.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        sdkInfo.setFileSize(fileSize);
        sdkInfo.setFileName(fileName);
        sdkInfo.setOperatorName("码农研究僧");
        sdkInfo.setUploadUrl(getUploadUrl);
        sdkInfo.setDownloadUrl(getDownloadUrl);
        SdkInfo insert = mongoTemplate.insert(sdkInfo);
    
        if(String.valueOf(insert) != null){
            logger.info(String.valueOf(insert));
        }else{
            logger.info("Failed to insert data");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.2 下载文件

    思路:由于mongo的数据库以及存储了下载链接,通过查询mongo的数据库,之后对应的链接进行重定向即可下载

    controller类:

    // http://127.0.0.1:10000/file/download
    @RequestMapping(value = "file/download" , method = RequestMethod.GET)
    public void fileDownLoad(@RequestParam("_id") String id, HttpServletResponse response){
        String getDownloadUrl = mongoService.findmongo(id);
        try {
        	// 链接的重定向,使得直接条状下载
            response.sendRedirect(getDownloadUrl);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    接口:public String findmongo(String id);
    接口实现类:

    @Override
    public String findmongo(String id){
    	// 通过每一行的关键信息查找对应某一行
        Query query = new Query(Criteria.where("id").is(id));
        List<SdkInfo> configs = mongoTemplate.find(query, SdkInfo.class);
    	
    	// 获取这一行的对应下载数据的链接
        logger.info("文件下载链接:" + configs.get(0).getDownloadUrl());
    
        return configs.get(0).getDownloadUrl();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.3 删除文件

    思路:上传与删除一样,需要对服务器进行操作之后在对数据库进行操作

    服务器的操作需要对接aws s3(省略)
    删除数据库的代码模块(通过form表单 获取对应的某个字段来或者这一行数据,之后删除这一行数据即可)

    @Override
    public void deletemongo(String id) {
        Query query = new Query(Criteria.where("_id").is(id));
        mongoTemplate.remove(query, SdkInfo.class);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.4 显示所有文件

    对应回显在前端是通过什么字段值,做好规范约束
    前端的规范约束是这个:

    *接口需要支持的参数:
    page: Int // 当前页码
    size: Int // 每页条数
    
    *接口返回的字段规范如下:
    {
        code:0,
        data:{
            list:[
                {
                    id: Int|String,
                    ...
                }
            ]
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    对应接口规范,代码为:

    private final MongoService mongoService;
    
    // http://127.0.0.1:10000/file/getAllFiles
    @RequestMapping(value =  "file/getAllFiles" , method = RequestMethod.GET)
    public Object  getAllFiles(@RequestParam("page") int page,
                               @RequestParam("size") int size){
        Map<String, Object> dataMap = new HashMap<>();
        Map<String, Object> listMap = new HashMap<>();
        try {
    
            List<Object> list = mongoService.showList();
            listMap.put("list",list);
            dataMap.put("data", listMap);
            dataMap.put("code", 0);
            dataMap.put("message", "查询成功");
        } catch (Exception e) {
            e.printStackTrace();
            dataMap.put("data", "");
            dataMap.put("code", 500);
            dataMap.put("message", "查询失败");
        }
        logger.info(""+dataMap);
        return dataMap;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    书写接口类:

    public List<Object> showList();
    
    • 1

    接口实现类:

    // SdkInfo.class是我定义的一个类
    @Override
    public List<Object> showList() {
        Query query = new Query();
        List<SdkInfo> configs = mongoTemplate.find(query, SdkInfo.class);
        List<Object> list = new ArrayList<Object>();
        configs.forEach(config -> {
            Map<String, String> map = new HashMap<>();
            map.put("_id",config.getId());
            map.put("文件名",config.getFileName());
            map.put("文件大小", config.getFileSize());
            map.put("创建时间", config.getCreateTime());
            map.put("上传用户",config.getOperatorName());
            map.put("下载链接",config.getDownloadUrl());
            list.add(map);
        });
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    SketchUp做效果图什么配置要求?创意云支持SketchUp一键云渲染
    程序员追星 - Gerald Jay Sussman
    python 笔记:h5py 读取HDF5文件
    用Python爬取古诗文网的各类古诗
    【Java面向对象】继承的认识与实现(2) 关键字 this 与 super 区别
    2022年重庆自考本科怎么报考,需要哪些条件?
    JAVA初阶——运算符
    免费api接口集合分享,再也不怕找不到免费api了
    java若依框架代码生成工具使用(前后端分离版)
    mac 版本 Lightroom Classic 2024 正式版来了 七个有趣的新功能值得更新
  • 原文地址:https://blog.csdn.net/weixin_47872288/article/details/126153304