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

青灯夜游
リリース: 2023-03-24 19:34:12
転載
1558 人が閲覧しました

ファイルのアップロードおよびダウンロード機能を実装するにはどうすればよいですか?以下の記事では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 サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!