Maison > outils de développement > git > Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

青灯夜游
Libérer: 2023-03-24 19:34:12
avant
1666 Les gens l'ont consulté

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers ? L'article suivant vous présentera comment implémenter les fonctions de téléchargement et de téléchargement de fichiers basées sur gitee. J'espère qu'il vous sera utile !

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

Sélection de solutions

Le téléchargement et le téléchargement de fichiers sont les fonctions principales de notre projet. Nous avons également intégré et optimisé le projet de démarrage précédent pour réaliser cette fonction.

Pour l'upload et le téléchargement de fichiers, Alibaba Cloud OSS et Huawei Cloud OSS sont généralement utilisés. Ils sont très simples à utiliser et le officiel propose une interface graphique. Cependant, ces méthodes nécessitent des frais de stockage en fonction du montant et sont similaires à gitee. et sont implémentés en appelant l'interface officielle, parce que je suis en phase d'apprentissage, j'ai choisi de créer un entrepôt dans gitee, d'utiliser l'API officielle pour lancer les fonctions de téléchargement et de suppression de fichiers dans l'entrepôt, et d'utiliser l'adresse du fichier stockée dans. la base de données pour télécharger le fichier sur le client du navigateur.

Conception des tables de base de données

Temporairement, seules deux tables de base de données sont utilisées pour implémenter les fonctions de base, l'une est une table de fichiers et l'autre est une table de dossiers

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;
}
Copier après la connexion
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;
}
Copier après la connexion

Construisez un entrepôt de gîtes

Ouvrez d'abord votre propre gîte new Un entrepôt, remplissez le nom, vérifiez l'entrepôt d'initialisation et définissez-le comme open source après la création

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

Une fois l'entrepôt créé, ouvrez la "Page d'accueil personnelle" -> "Paramètres personnels" -> "Privé Token" consiste à générer vous-même un nouveau jeton privé pour l'authentification lors de l'appel à l'interface officielle.

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

Générez-le directement sans vous soucier des options. Attention à bien sauvegarder votre token car il ne sera affiché qu'une seule fois.

Compilation de la classe d'outils de lit d'images de gîte

Utilisé ici pour copier directement ce que d'autres ont écrit. Notez que le jeton privé, l'espace personnel, le nom de l'entrepôt et l'adresse de stockage par défaut doivent également être remplacés par les vôtres. Ces informations sont utilisées pour lancer une demande de téléchargement vers le référentiel gitee via la classe d'outils HttpUtil.

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>
Copier après la connexion

Interface de téléchargement de fichiers

Le processus de téléchargement de fichier consiste à transmettre l'objet fichier et les informations associées au front-end. Ensuite, nous lançons une demande à gitee pour transférer le fichier vers l'entrepôt une fois le téléchargement réussi. , l'adresse de téléchargement renvoyée et les informations associées seront stockées dans la base de données.

Classe d'outils intermédiaire

Ici, nous écrivons d'abord une classe d'outils intermédiaire pour lancer des requêtes et obtenir des résultats Si ce code est également écrit dans le service, le code semblera trop long et compliqué, je l'écrirai donc. séparément.

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;
    }
}
Copier après la connexion

Controller

Après avoir obtenu le fichier et les informations, le contrôleur appelle la classe d'outils intermédiaire pour télécharger le fichier, puis obtient l'identifiant utilisateur de l'en-tête de la requête, obtient les informations sur le fichier de l'objet renvoyé et les stocke dans la classe File, puis utilise mybatisplus pour enregistrer l'objet. Enregistrez-le simplement dans la base de données.

Le service
@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>
Copier après la connexion
Ev est relativement simple. Définir une durée de stockage pour appeler Mapper et stocker dans

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

test d'interface

Nous téléchargeons simplement un fichier

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

pour voir si le gîte et les bases de données ont des résultats correspondants

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

.

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

L'identifiant ici est 2 car une donnée a été supprimée auparavant et vous souhaitez simplement tronquer la table depuis le début.

Interface de téléchargement de fichiers

Le téléchargement de fichiers m'a dérangé au début. Il existe deux façons : la première consiste à écrire directement l'objet fichier à l'adresse du dossier local fournie par l'utilisateur, et la seconde consiste à télécharger le fichier dans le navigateur. . Enfin, la deuxième méthode a été choisie car l'utilisateur n'a pas besoin de définir l'adresse de téléchargement et peut voir le processus de téléchargement lors du téléchargement dans le navigateur. L'ensemble du processus consiste à utiliser l'adresse de téléchargement pour convertir le fichier en flux de fichiers et l'écrire. dans un tableau d'octets, puis utilisez le navigateur pour télécharger via la méthode qui écrit un tableau d'octets dans le flux de sortie.

🎜contrôleur🎜🎜🎜 Utilisez l'ID de fichier pour trouver d'abord l'adresse correspondante dans la base de données, puis utilisez l'adresse pour effectuer les opérations suivantes. 🎜
/**
     * 文件下载接口
     * @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>
Copier après la connexion
🎜 Ici, vous devez écrire une classe d'outils pour obtenir le nom du fichier, sinon le navigateur ne connaîtra pas le type de fichier après le téléchargement🎜
/**
     * 获取url中的文件名(取到最后一个/后面的就是文件名)
     * @param url 文件地址
     * @return
     */
    public static String getFileName(String url) {
        if(!url.equals("")){
        return url.substring(url.lastIndexOf("/")+1);
        }
        else return "文件地址错误";
    }
Copier après la connexion

接口测试 

  发送请求完成下载

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur 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 + " 删除成功!");
    }
Copier après la connexion

service

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

/**
     * 删除文件
     * @param fileId 文件id
     * @return
     */
    @Override
    public String delFile(Long fileId) {
        String url = fileMapper.selectById(fileId).getFilePath();
        fileMapper.deleteById(fileId);
        return url;
    }
Copier après la connexion

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>
Copier après la connexion

接口测试

发送请求删除文件

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

 查看数据库和gitee仓库

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

Comment implémenter la fonction de téléchargement et de téléchargement de fichiers basés sur gitee

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal