搜尋
首頁開發工具Git怎麼基於gitee實作上傳下載檔案的功能

怎麼實現檔案的上傳下載功能?以下這篇文章為大家介紹一下基於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;

/**
 * @ClassName UploadGiteeImgBedUtil
 * @Author ityz
 * @Date 2022/11/23 16:38
 * @Description Gitee图床工具类
 */
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
    /**
     * 新建(POST)、获取(GET)、删除(DELETE)文件:()中指的是使用对应的请求方式
     * %s =>仓库所属空间地址(企业、组织或个人的地址path)  (owner)
     * %s => 仓库路径(repo)
     * %s => 文件的路径(path)
     */
    private static final String API_CREATE_POST = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";


    /**
     * 生成创建(获取、删除)的指定文件路径
     * @param originalFilename 原文件名
     * @param path 存储文件路径
     * @return
     */
    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;
    }

    /**
     * 获取创建文件的请求体map集合:access_token、message、content
     * @param multipartFile 文件字节数组
     * @return 封装成map的请求体集合
     */
    private static Map<string> getUploadBodyMap(byte[] multipartFile){
        HashMap<string> bodyMap = new HashMap(3);
        bodyMap.put("access_token", GiteeImgBedUtil.ACCESS_TOKEN);
        bodyMap.put("message", "add file!");
        bodyMap.put("content", Base64.encode(multipartFile));
        return bodyMap;
    }

    /**
     * 创建普通携带请求体集合内容
     * @param map 额外参数
     * @param message 请求信息
     * @return
     */
    private static Map<string> getCommonBodyMap(HashMap map, String message){
        HashMap<string> 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;

    /**
     * 上传文件
     * @param filename 文件名称
     * @param path 路径
     * @param sha 必备参数from 获取仓库具体路径下的内容
     * @return
     */
    public static String uploadFile(String path, String originalFilename, byte[] data){
        String targetURL = GiteeImgBedUtil.createUploadFileUrl(originalFilename,path);
        //请求体封装
        Map<string> uploadBodyMap = GiteeImgBedUtil.getUploadBodyMap(data);
        return HttpUtil.post(targetURL, uploadBodyMap);
    }


    /**
     * 删除指定path路径下的文件
     * @param filename 文件名称
     * @param path 路径
     * @param sha 必备参数from 获取仓库具体路径下的内容
     * @return
     */
    public static String deleteFile(String path,String sha){
        String delFileUrl = createDelFileUrl(path);
        HashMap<string> needMap = new HashMap(1);
        needMap.put("sha",sha);//添加sha参数
        return HttpUtil.createRequest(Method.DELETE, delFileUrl)
                .form(getCommonBodyMap(needMap,"del file!"))  //构建请求表单
                .timeout(TIMEOUT)
                .execute().body();
    }

    /**
     * 获取仓库具体路径下的内容,主要是获取 sha
     * @param path
     * @return
     */
    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();
    }

}</string></string></string></string></string></string>

檔案上傳介面 

  檔案上傳的過程為前端傳入檔案物件和相關資訊然後我們向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;

/**
 * gitee文件操作api
 */
@Slf4j
public class GiteeApi {
    /**
     * 上传文件api
     * @param multipartFile 前端传入的文件对象
     * @param folder 文件所存文件夹名称
     * @return gitee的api上传返回值的json对象
     * @throws IOException
     */
    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;

    /**
     * 文件上传接口
     * @param multipartFile 上传的文件对象
     * @param fileCover 文件的描述信息
     * @param folderId 文件所属的文件夹id
     * @return 用户文件地址
     * @throws IOException
     */
    @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));
    }
}</string>

  service比較簡單,設定一個儲存時間呼叫mapper存入就行

/**
     * 上传文件
     *
     * @param file 用于向数据库储存的文件对象
     */
    @Override
    public void fileUpload(File file) {
        file.setCreateTime(new Date());
        fileMapper.insert(file);
    }

介面測試

  我們隨便上傳一個檔案

怎麼基於gitee實作上傳下載檔案的功能

   查看gitee和資料庫是否有對應結果

怎麼基於gitee實作上傳下載檔案的功能

 怎麼基於gitee實作上傳下載檔案的功能

   這裡id為2是因為之前刪除了一條數據,想要從頭開始截斷表就行。

檔案下載介面

  檔案下載最初比較困擾我,有兩種方式,第一種是直接將檔案物件寫入到使用者提供的本機資料夾位址,第二種是將檔案下載到瀏覽器。最後選擇了第二種方式,因為使用者不用設定下載位址而且在瀏覽器下載可以看到下載過程,整個流程是利用下載位址將檔案轉換為檔案流寫入位元組數組,在利用瀏覽器透過下載的方式寫出位元組數組到輸出流。

controller

  使用檔案id先從資料庫查到對應位址然後利用位址完成後續作業。

/**
     * 文件下载接口
     * @param fileId 文件id
     * @param response http响应对象
     * @return 下载结果
     */
    @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);
        }
    }</string>

  這裡需要一個寫一個取得檔案名稱的工具類,不然下載之後瀏覽器不知道檔案類型

/**
     * 获取url中的文件名(取到最后一个/后面的就是文件名)
     * @param url 文件地址
     * @return
     */
    public static String getFileName(String url) {
        if(!url.equals("")){
        return url.substring(url.lastIndexOf("/")+1);
        }
        else return "文件地址错误";
    }

接口测试 

  发送请求完成下载

怎麼基於gitee實作上傳下載檔案的功能

文件删除接口

中间工具类

/**
     * 删除文件api
     * @param url 文件地址
     */
    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

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

/**
     * 删除文件
     * @param fileId 文件id
     * @return
     */
    @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);
        }
    }</string>

接口测试

发送请求删除文件

怎麼基於gitee實作上傳下載檔案的功能

 查看数据库和gitee仓库

怎麼基於gitee實作上傳下載檔案的功能

怎麼基於gitee實作上傳下載檔案的功能

   自此完成了文件的上传和下载功能,大家有需要的可以参考。

(学习视频分享:编程基础视频

以上是怎麼基於gitee實作上傳下載檔案的功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:csdn。如有侵權,請聯絡admin@php.cn刪除
GitHub:開源和軟件開發的樞紐GitHub:開源和軟件開發的樞紐Apr 15, 2025 am 12:10 AM

GitHub是一個基於Git的版本控制系統託管平台,提供版本控制、協作開發和社區交流功能。使用GitHub可以提高開發效率和代碼質量。

git and github:有什麼關係?git and github:有什麼關係?Apr 14, 2025 am 12:10 AM

Git和GitHub是不同的工具:Git是用於版本控制的軟件,GitHub是基於Git的在線平台。 1.Git允許你跟踪文件變化和協同開發。 2.GitHub提供代碼託管和協作工具,增強團隊開發效率。

GitHub:開發人員和項目的平台GitHub:開發人員和項目的平台Apr 13, 2025 am 12:01 AM

GitHub的核心功能包括版本控制、分支管理、代碼審查、問題跟踪和項目管理。 1.版本控制與分支管理基於Git,允許追踪代碼變更和實驗性開發。 2.代碼審查通過PullRequest實現,提升代碼質量和團隊協作。 3.問題跟踪與項目管理通過Issues和項目管理板進行,提高項目透明度和可追踪性。

行動中的github:示例和用例行動中的github:示例和用例Apr 12, 2025 am 12:16 AM

GitHub是提升軟件開發效率和質量的強大工具。 1)版本控制:通過Git管理代碼變更。 2)PullRequests:進行代碼審查,提高代碼質量。 3)Issues:跟踪bug和項目進度。 4)GitHubActions:自動化構建、測試和部署流程。

git vs. github:版本控制和代碼託管git vs. github:版本控制和代碼託管Apr 11, 2025 am 11:33 AM

Git是版本控制系統,GitHub是基於Git的代碼託管平台。 Git用於管理代碼版本,支持本地操作;GitHub提供在線協作工具,如Issue跟踪和PullRequest。

什麼是簡單的話?什麼是簡單的話?Apr 09, 2025 am 12:12 AM

Git是一個開源的分佈式版本控制系統,幫助開發者跟踪文件變化、協同工作和管理代碼版本。它的核心功能包括:1)記錄代碼修改,2)回退到之前版本,3)協同開發,4)創建和管理分支進行並行開發。

git和github相同嗎?git和github相同嗎?Apr 08, 2025 am 12:13 AM

Git和GitHub不是同一回事。 Git是版本控制系統,GitHub是基於Git的代碼託管平台。 Git用於管理代碼版本,GitHub提供在線協作環境。

如何將github用於HTML?如何將github用於HTML?Apr 07, 2025 am 12:13 AM

使用GitHub管理HTML項目的原因是它提供了版本控制、協作開發和展示作品的平台。具體步驟包括:1.創建並初始化Git倉庫,2.添加和提交HTML文件,3.推送到GitHub,4.使用GitHubPages部署網頁,5.利用GitHubActions自動化構建和部署。此外,GitHub還支持代碼審查、Issue和PullRequest功能,幫助優化和協作開發HTML項目。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具