文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于gitee如何实现上传下载文件的功能

2023-07-05 16:16

关注

本文小编为大家详细介绍“基于gitee如何实现上传下载文件的功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“基于gitee如何实现上传下载文件的功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

方案的选择

文件的上传和下载是我们这个项目的核心功能,也是整合优化了一下以前的boot项目来实现这个功能。

对于文件的上传和下载一般是使用阿里云OSS、华为云OSS这些,很好用而且官方提供了图形界面,但是这些方式都需要按量储存收费并且和gitee相似都是去调用官方接口实现功能,因为我是在学习阶段,所以选择了在gitee搭建了一个仓库,利用官方的api向仓库发起文件的上传、删除功能,并且利用数据库储存的文件地址实现将文件下载到浏览器客户端。

数据库表的设计

数据库的表暂时只用了两张来实现基本功能,一个是文件表,一个是文件夹表

public class File {    @TableId(type = IdType.AUTO)    private Long id;    private String fileName;    private String filePath;    private String fileSize;    @TableField(fill = FieldFill.INSERT)    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")    private Date createTime;    private Long userId;    private Long folderId;    //分享次数    private Integer shareTimes;    //文件描述    private String fileCover;}
public class Folder {    @TableId(type = IdType.AUTO)    private Long id;    private String folderName;    private Long fatherId;  //父文件夹id,为0表示没有最上层文件夹    private Long userId;    private String folderCover;    private Boolean folderPermissions;    @TableField(fill = FieldFill.INSERT)    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")    private Date createTime;}

搭建gitee仓库

首先打开自己的gitee新建一个仓库,填写名称,勾选初始化仓库,创建好之后设置为开源

基于gitee如何实现上传下载文件的功能

仓库创建好之后打开“个人主页”—>“个人设置”---->“私人令牌”为自己生成一个新的私人令牌用于调用官方接口时的认证。

基于gitee如何实现上传下载文件的功能

生成时不用管选项直接生成,注意保存自己的令牌,因为只会展示一次。

gitee图床工具类的编写

这里用的别人写好的直接copy就行,注意里面的私人令牌、个人空间、仓库名、默认存储地址要改成自己的,这个工具类也就是利用这些信息通过HttpUtil工具类向gitee仓库发起上传请求。

package com.ityz.file.util;import cn.hutool.core.codec.Base64;import cn.hutool.http.HttpUtil;import cn.hutool.http.Method;import java.util.HashMap;import java.util.Map;import java.util.UUID;public class GiteeImgBedUtil {        private static final String ACCESS_TOKEN = "0616f0e894e3c264bac45591e34a43bc";  //这里不展示我自己的了,需要你自己补充        private static final String OWNER = "procedure-yuan-yanzu";        private static final String REPO = "files";        public static final String PATH = "files/";    //API        private static final String API_CREATE_POST = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";        private static String createUploadFileUrl(String originalFilename,String path){        String targetPath = path == null ? GiteeImgBedUtil.PATH : path;        //获取文件后缀        String suffix = FileUtil.getFileSuffix(originalFilename);        //拼接存储的图片名称        String fileName = System.currentTimeMillis()+"_"+ UUID.randomUUID().toString()+suffix;        //填充请求路径        String url = String.format(GiteeImgBedUtil.API_CREATE_POST,                GiteeImgBedUtil.OWNER,                GiteeImgBedUtil.REPO,                targetPath + fileName);        return url;    }    private static String createDelFileUrl(String path){        //填充请求路径        String url = String.format(GiteeImgBedUtil.API_CREATE_POST,                GiteeImgBedUtil.OWNER,                GiteeImgBedUtil.REPO,                path);        return url;    }    private static String createGetUrl(String path){        String targetPath = path == null ? GiteeImgBedUtil.PATH : path;        //填充请求路径        String url = String.format(GiteeImgBedUtil.API_CREATE_POST,                GiteeImgBedUtil.OWNER,                GiteeImgBedUtil.REPO,                targetPath);        return url;    }        private static Map<String,Object> getUploadBodyMap(byte[] multipartFile){        HashMap<String, Object> bodyMap = new HashMap<>(3);        bodyMap.put("access_token", GiteeImgBedUtil.ACCESS_TOKEN);        bodyMap.put("message", "add file!");        bodyMap.put("content", Base64.encode(multipartFile));        return bodyMap;    }        private static Map<String,Object> getCommonBodyMap(HashMap map, String message){        HashMap<String, Object> bodyMap = new HashMap<>(2);        bodyMap.put("access_token", GiteeImgBedUtil.ACCESS_TOKEN);        bodyMap.put("message", message);        if (map != null){            bodyMap.putAll(map);        }        return bodyMap;    }        //超时    private static int TIMEOUT = 10 * 1000;        public static String uploadFile(String path, String originalFilename, byte[] data){        String targetURL = GiteeImgBedUtil.createUploadFileUrl(originalFilename,path);        //请求体封装        Map<String, Object> uploadBodyMap = GiteeImgBedUtil.getUploadBodyMap(data);        return HttpUtil.post(targetURL, uploadBodyMap);    }        public static String deleteFile(String path,String sha){        String delFileUrl = createDelFileUrl(path);        HashMap<String, Object> needMap = new HashMap<>(1);        needMap.put("sha",sha);//添加sha参数        return HttpUtil.createRequest(Method.DELETE, delFileUrl)                .form(getCommonBodyMap(needMap,"del file!"))  //构建请求表单                .timeout(TIMEOUT)                .execute().body();    }        public static String getSha(String path){        String getShaUrl = createDelFileUrl(path);        return HttpUtil.createRequest(Method.GET, getShaUrl)                .form(getCommonBodyMap(null, "get sha!"))                .timeout(TIMEOUT)                .execute().body();    }}

文件上传接口

文件上传的过程为前端传入文件对象和相关信息然后我们向gitee发起请求将文件传到仓库,上传成功之后在将返回的下载地址和相关信息存入数据库当中。

中间工具类

这里我们先来编写一个中间工具类来发起请求和拿到结果,这个代码也写在服务当中的话会显得代码太长太复杂所以我单独拿出来写。

import cn.hutool.json.JSONObject;import cn.hutool.json.JSONUtil;import com.ityz.common.constants.GiteeConstant;import lombok.extern.slf4j.Slf4j;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;@Slf4jpublic class GiteeApi {        public static JSONObject upload(MultipartFile multipartFile,String folder) throws IOException {        log.info("uploadFile()请求已来临...");        //根据文件名生成指定的请求url        String originalFilename = multipartFile.getOriginalFilename();        if (originalFilename == null) {            log.info("服务器接收文件失败!");        }        //Gitee请求:发送上传文件请求        String JSONResult = GiteeImgBedUtil.uploadFile(folder, originalFilename, multipartFile.getBytes());        //解析响应JSON字符串        //上传txt文件时会出问题,没解决        JSONObject jsonObj = JSONUtil.parseObj(JSONResult);        //请求失败        if (jsonObj.getObj(GiteeConstant.RESULT_BODY_COMMIT) == null) {            log.info("上传文件失败!");        }        //请求成功:返回下载地址        JSONObject content = JSONUtil.parseObj(jsonObj.getObj(GiteeConstant.RESULT_BODY_CONTENT));        log.info("上传成功,下载地址为:" + content.getStr(GiteeConstant.RESULT_BODY_DOWNLOAD_URL));        return content;    }}

Controller

controller拿到文件和信息后调用中间工具类上传文件,然后从请求头中拿到用户id,从返回对象中拿到文件信息存入File类当中然后使用mybatisplus将对象存入数据库就行。

@RestController@Slf4j@RequestMapping("/file")public class FileController {    @Autowired    private FileService fileService;    @Autowired    private HttpServletRequest request;        @PostMapping("/upload")    public Result<String> uploadFile(@RequestParam("file") MultipartFile multipartFile            , @RequestParam("fileCover") String fileCover            , @RequestParam("folderId") Long folderId) throws IOException {        JSONObject content = GiteeApi.upload(multipartFile, "test/");        //获取userId        Long userId = Long.valueOf(TokenUtil.parseToken(request.getHeader("token")));        File file = new File();        file.setFileCover(fileCover);        file.setUserId(userId);        file.setFolderId(folderId);        file.setFileName(content.getStr(GiteeConstant.RESULT_BODY_NAME));;        file.setFileSize(content.getStr(GiteeConstant.RESULT_BODY_SIZE));        file.setFilePath(content.getStr(GiteeConstant.RESULT_BODY_DOWNLOAD_URL));        fileService.fileUpload(file);        return new Result<>(ResultCode.SUCCESS,ResultCode.UP_FILE_SUCCESS,content.getStr(GiteeConstant.RESULT_BODY_DOWNLOAD_URL));    }}

service比较简单,设置一个储存时间调用mapper存入就行

    @Override    public void fileUpload(File file) {        file.setCreateTime(new Date());        fileMapper.insert(file);    }

接口测试

我们随便上传一个文件

基于gitee如何实现上传下载文件的功能

查看gitee和数据库是否有相应结果

基于gitee如何实现上传下载文件的功能

这里id为2是因为之前删除了一条数据,想要从头开始截断表就行。

文件下载接口

文件下载最初比较困扰我,有两种方式,第一种是直接将文件对象写入到用户提供的本地文件夹地址,第二种是将文件下载到浏览器。最终选择了第二种方式,因为用户不用设置下载地址而且在浏览器下载可以看到下载过程,整个流程是利用下载地址将文件转换为文件流写入字节数组,在利用浏览器通过下载的方式写出字节数组到输出流。

controller

使用文件id先从数据库查到相应地址然后利用地址完成后续操作。

    @GetMapping("/download")    public Result<String> download(Long fileId,HttpServletResponse response) {        try {            String downloadUrl = fileService.downloadFile(fileId);            URL url = new URL(downloadUrl);            URLConnection conn = url.openConnection();            InputStream bis = conn.getInputStream();            byte[] bytes = new byte[bis.available()];            OutputStream os = response.getOutputStream();            // 从文件流读取字节到字节数组中            while (bis.read(bytes) != -1) {                // 重置 response                response.reset();                // 设置 response 的下载响应头                response.setContentType("application/x-download");                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(FileUtil.getFileName(downloadUrl), "UTF-8"));  // 注意,这里要设置文件名的编码,否则中文的文件名下载后不显示                // 写出字节数组到输出流                os.write(bytes);                // 刷新输出流                os.flush();            }            return new Result<>(ResultCode.SUCCESS,ResultCode.DOWN_FILE_SUCCESS);        }catch (Exception e){            e.printStackTrace();            return new Result<>(ResultCode.FAIL,ResultCode.DOWN_FILE_FAIL);        }    }

这里需要一个编写获取文件名的工具类,不然下载之后浏览器不知道文件类型

    public static String getFileName(String url) {        if(!url.equals("")){        return url.substring(url.lastIndexOf("/")+1);        }        else return "文件地址错误";    }

接口测试

发送请求完成下载

基于gitee如何实现上传下载文件的功能

文件删除接口

中间工具类

    public static void del(String url){        if (!url.equals("") && !url.contains("master/")) {            log.info("url:" + url + " 无法解析路径!");        }        String path = url.substring(url.indexOf("master/") + 7);        log.info("解析取得待删除路径:" + path);        String shaResult = GiteeImgBedUtil.getSha(path);        JSONObject jsonObj = JSONUtil.parseObj(shaResult);        String sha = jsonObj.getStr(GiteeConstant.RESULT_BODY_SHA);        //3、Gitee请求:发送删除请求        String JSONResult = GiteeImgBedUtil.deleteFile(path, sha);        jsonObj = JSONUtil.parseObj(JSONResult);        if (jsonObj.getObj(GiteeConstant.RESULT_BODY_COMMIT) == null) {            log.info("删除文件失败!");        }        log.info("文件路径为:" + path + " 删除成功!");    }

service

获取文件地址并删除数据库数据

    @Override    public String delFile(Long fileId) {        String url = fileMapper.selectById(fileId).getFilePath();        fileMapper.deleteById(fileId);        return url;    }

controller

**     * 删除文件接口     * @param fileId 前端传入的文件id     * @return     */    @GetMapping("/del")    public Result<String> delFile(Long fileId) {        try {            String url = fileService.delFile(fileId);            GiteeApi.del(url);            return new Result<>(ResultCode.SUCCESS,ResultCode.DEL_FILE_SUCCESS);        }        catch (Exception e){            e.printStackTrace();            return new Result<>(ResultCode.FAIL,ResultCode.DEL_FILE_FAIL);        }    }

接口测试

发送请求删除文件

基于gitee如何实现上传下载文件的功能

查看数据库和gitee仓库

基于gitee如何实现上传下载文件的功能

读到这里,这篇“基于gitee如何实现上传下载文件的功能”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯