目次
ソリューションの選択
データベース テーブルの設計
Gitee ウェアハウスを構築する
gitee 画像ベッド ツール クラスのコンパイル
ファイル アップロード インターフェイス
中間ツール クラス
Controller
インターフェイス テスト
接口测试 
文件删除接口
中间工具类
service
controller
接口测试
ホームページ 開発ツール Git giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

Mar 24, 2023 pm 07:34 PM
git gitee

ファイルのアップロードおよびダウンロード機能を実装するにはどうすればよいですか?以下の記事ではgiteeをベースにしたファイルアップロード・ダウンロード機能の実装方法を紹介しますので、ご参考になれば幸いです。

giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

ソリューションの選択

ファイルのアップロードとダウンロードはプロジェクトの中核機能であり、以前のブートの統合と最適化も行います。この機能を実装するプロジェクト。

ファイルのアップロードとダウンロードには、Alibaba Cloud OSS や Huawei Cloud OSS が一般的に使用され、非常に使いやすく、公式にグラフィカル インターフェイスが提供されていますが、これらの方法は容量に応じてストレージ料金が必要であり、同様の方法です。 gitee. 公式インターフェイスを呼び出して関数を実装します。学習段階なので、gitee にウェアハウスを構築し、公式 API を使用してファイルのアップロードとウェアハウスへの削除機能を開始し、に保存されているファイル アドレスを使用することにしました。データベースを使用してファイルをブラウザ サーバー クライアントにダウンロードします。

データベース テーブルの設計

データベース テーブルは、基本的な機能を実装するために 2 つのテーブルのみを使用します。1 つはファイル テーブル、もう 1 つはフォルダー テーブルです。

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をベースにファイルをアップロード・ダウンロードする機能を実装する方法

# 生成時のオプションについては心配する必要はありません。独自のトークンは 1 回しか表示されないため、慎重に保存してください。

gitee 画像ベッド ツール クラスのコンパイル

他の人が書いたものをコピーし、プライベート トークン、個人スペース、ウェアハウス名、内部のデフォルトに注意してください。ストレージ アドレスは独自のものに変更する必要があります。このツール クラスはこの情報を使用して、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

コントローラーはファイルと情報を取得した後、中間ツール クラスを呼び出してファイルをアップロードし、リクエスト ヘッダーからユーザー 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>
ログイン後にコピー

このサービスは比較的シンプルで、保存時間を設定し、マッパーを呼び出して保存するだけです。

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

インターフェイス テスト

ファイルをアップロードできます任意

giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

gitee とデータベースに対応する結果があるかどうかを確認します

giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

giteeをベースにファイルをアップロード・ダウンロードする機能を実装する方法

#ここでの ID は 2 です。データの一部が削除された場合、テーブルを最初から切り詰めるだけで済みます。

ファイル ダウンロード インターフェイス

ファイルのダウンロードは最初は面倒でしたが、方法は 2 つあり、1 つはユーザーが指定したローカル フォルダーにファイル オブジェクトを直接書き込む方法です。 2 つ目は、ファイルをブラウザにダウンロードすることです。最後に、ユーザーがダウンロード アドレスを設定する必要がなく、ブラウザでダウンロードするときにダウンロード プロセスを確認できるため、最後に 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 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

H5プロジェクトの実行方法 H5プロジェクトの実行方法 Apr 06, 2025 pm 12:21 PM

H5プロジェクトを実行するには、次の手順が必要です。Webサーバー、node.js、開発ツールなどの必要なツールのインストール。開発環境の構築、プロジェクトフォルダーの作成、プロジェクトの初期化、コードの書き込み。開発サーバーを起動し、コマンドラインを使用してコマンドを実行します。ブラウザでプロジェクトをプレビューし、開発サーバーURLを入力します。プロジェクトの公開、コードの最適化、プロジェクトの展開、Webサーバーの構成のセットアップ。

Giteeページ静的なWebサイトの展開に失敗しました:単一のファイル404エラーをトラブルシューティングと解決する方法 Giteeページ静的なWebサイトの展開に失敗しました:単一のファイル404エラーをトラブルシューティングと解決する方法 Apr 04, 2025 pm 11:54 PM

GiteEpages静的Webサイトの展開が失敗しました:404エラーのトラブルシューティングと解像度Giteeを使用する

Beego ormのモデルに関連付けられているデータベースを指定する方法は? Beego ormのモデルに関連付けられているデータベースを指定する方法は? Apr 02, 2025 pm 03:54 PM

Beegoormフレームワークでは、モデルに関連付けられているデータベースを指定する方法は?多くのBEEGOプロジェクトでは、複数のデータベースを同時に操作する必要があります。 Beegoを使用する場合...

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Apr 02, 2025 pm 04:54 PM

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

H5ページの生産には継続的なメンテナンスが必要ですか? H5ページの生産には継続的なメンテナンスが必要ですか? Apr 05, 2025 pm 11:27 PM

H5ページは、コードの脆弱性、ブラウザー互換性、パフォーマンスの最適化、セキュリティの更新、ユーザーエクスペリエンスの改善などの要因のため、継続的に維持する必要があります。効果的なメンテナンス方法には、完全なテストシステムの確立、バージョン制御ツールの使用、定期的にページのパフォーマンスの監視、ユーザーフィードバックの収集、メンテナンス計画の策定が含まれます。

SQL.Openを使用するとき、DSNが空に渡されたときにエラーを報告しないのはなぜですか? SQL.Openを使用するとき、DSNが空に渡されたときにエラーを報告しないのはなぜですか? Apr 02, 2025 pm 12:54 PM

SQL.Openを使用する場合、DSNがエラーを報告しないのはなぜですか? GO言語では、sql.open ...

See all articles