Heim >Entwicklungswerkzeuge >Idiot >So implementieren Sie die Funktion zum Hoch- und Herunterladen von Dateien basierend auf Gitee
Wie implementiert man die Datei-Upload- und Download-Funktion? Im folgenden Artikel erfahren Sie, wie Sie Datei-Upload- und Download-Funktionen auf Basis von Gitee implementieren. Ich hoffe, dass er Ihnen weiterhilft!
Das Hochladen und Herunterladen von Dateien sind die Kernfunktionen unseres Projekts. Um diese Funktion zu erreichen, haben wir auch das vorherige Boot-Projekt integriert und optimiert.
Zum Hochladen und Herunterladen von Dateien werden im Allgemeinen Alibaba Cloud OSS und Huawei Cloud OSS verwendet. Sie sind sehr einfach zu verwenden und bieten eine grafische Oberfläche. Diese Methoden erfordern jedoch Speichergebühren basierend auf der Menge und ähneln Gitee. und werden durch Aufrufen der offiziellen Schnittstelle implementiert. Da ich mich in der Lernphase befinde, habe ich mich entschieden, ein Warehouse in Gitee zu erstellen, die offizielle API zum Initiieren von Datei-Upload- und Löschfunktionen in das Warehouse zu verwenden und die in gespeicherte Dateiadresse zu verwenden die Datenbank, um die Datei auf den Browser-Client herunterzuladen.
Vorübergehend werden nur zwei Datenbanktabellen verwendet, um Grundfunktionen zu implementieren, eine ist eine Dateitabelle und die andere ist eine Ordnertabelle
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; }
Öffnen Sie zunächst Ihr eigenes Gitee Neues Lager, geben Sie den Namen ein, überprüfen Sie das Initialisierungslager und legen Sie es nach der Erstellung als Open Source fest
Nachdem das Lager erstellt wurde, öffnen Sie „Persönliche Startseite“ -> „Persönliche Einstellungen“ -> „Privat“. „Token“ ist das Generieren eines neuen privaten Tokens zur Authentifizierung beim Aufruf der offiziellen Schnittstelle.
Generieren Sie es direkt, ohne sich um die Optionen kümmern zu müssen. Achten Sie darauf, Ihr Token zu speichern, da es nur einmal angezeigt wird.
Wird hier verwendet, um direkt zu kopieren, was andere geschrieben haben. Beachten Sie, dass der private Token, der persönliche Bereich, der Lagername und die Standardspeicheradresse ebenfalls in Ihre eigene geändert werden müssen Diese Informationen werden verwendet, um über die HttpUtil-Toolklasse eine Upload-Anfrage an das Gitee-Repository zu initiieren.
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>
Der Prozess des Datei-Uploads besteht darin, das Dateiobjekt und die zugehörigen Informationen an das Frontend zu übergeben. Anschließend initiieren wir eine Anfrage an Gitee, um die Datei in das Warehouse zu übertragen , die zurückgegebene Download-Adresse und die zugehörigen Informationen werden in der Datenbank gespeichert.
Hier schreiben wir zunächst eine Mittelklasse für Werkzeuge, um Anfragen zu initiieren und Ergebnisse zu erhalten. Wenn dieser Code auch im Dienst geschrieben wird, scheint der Code zu lang und kompliziert zu sein, also werde ich ihn schreiben separat.
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; } }
Nachdem die Datei und die Informationen abgerufen wurden, ruft der Controller die Zwischentoolklasse auf, um die Datei hochzuladen. Anschließend ruft er die Benutzer-ID aus dem Anforderungsheader ab, ruft die Dateiinformationen aus dem zurückgegebenen Objekt ab und speichert sie in die File-Klasse und verwendet dann mybatisplus, um das Objekt zu speichern. Speichern Sie es einfach in der Datenbank.
@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>V -Dienst ist relativ einfach.
Die ID hier ist 2, da zuvor ein Datenelement gelöscht wurde und Sie die Tabelle einfach von Anfang an abschneiden möchten.
Schnittstelle zum Herunterladen von Dateien Das Herunterladen von Dateien hat mich zunächst gestört. Die erste Möglichkeit besteht darin, das Dateiobjekt direkt in die vom Benutzer angegebene lokale Ordneradresse zu schreiben, und die zweite darin, die Datei in den Browser herunterzuladen . . Schließlich wurde die zweite Methode gewählt, da der Benutzer die Download-Adresse nicht festlegen muss und den Download-Vorgang beim Herunterladen im Browser sehen kann. Der gesamte Vorgang besteht darin, die Download-Adresse zum Konvertieren der Datei in einen Dateistream und zum Schreiben zu verwenden Schreiben Sie es in ein Byte-Array und verwenden Sie dann den Browser, um es über die Methode herunterzuladen, die ein Byte-Array in den Ausgabestream schreibt. Controller/** * 上传文件 * * @param file 用于向数据库储存的文件对象 */ @Override public void fileUpload(File file) { file.setCreateTime(new Date()); fileMapper.insert(file); }Hier müssen Sie eine Toolklasse schreiben, um den Dateinamen zu erhalten, sonst kennt der Browser den Dateityp nach dem Herunterladen nicht
/** * 获取url中的文件名(取到最后一个/后面的就是文件名) * @param url 文件地址 * @return */ public static String getFileName(String url) { if(!url.equals("")){ return url.substring(url.lastIndexOf("/")+1); } else return "文件地址错误"; }
发送请求完成下载
/** * 删除文件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 + " 删除成功!"); }
获取文件地址并删除数据库数据
/** * 删除文件 * @param fileId 文件id * @return */ @Override public String delFile(Long fileId) { String url = fileMapper.selectById(fileId).getFilePath(); fileMapper.deleteById(fileId); return url; }
** * 删除文件接口 * @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仓库
自此完成了文件的上传和下载功能,大家有需要的可以参考。
(学习视频分享:编程基础视频)
Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Funktion zum Hoch- und Herunterladen von Dateien basierend auf Gitee. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!