乐享精致生活 Enjoy a fine life
有爱的人终会在路口相遇、相拥、相伴。
如何利用gitee搭建免费的图床,并且实现上传和下载
一、那些年的“执念”
前两天我们做了个网站,因为是个人的,图片存储是个问题,不想发到自己的服务器上占内存(钱有限),想着利用别人的免费图床,这个省了空间和钱,于是我找了很多,发现很多图床都有限制,比较是免费给你使用,不可能没有限制,毕竟没人这么有钱给你这样霍霍,而且,我们是那种白嫖的人吗?当然不(jiu)是(shi),我只是想给大伙某份福利,给大伙寻一免费的图床,终于找到了满足你们需求的图床,而且不会有图片丢失的风险(除非你偷偷把它删除了),那什么可以做免费图床呢,gitee,github都用过吧,其实应该都可,但是github毕竟是外国网站,访问太慢太受限了,所以我就选择了gitee
图片|来源于网络
二、环境准备
1、注册一个gitee账号,然后登录
2、进入设置(设置知道怎么进入吧,不知道?对就是那样进入的)
3、找到 私人令牌,然后生成令牌
4、接着在gitee上创建一个 公开 的仓库
到这里图片存储的地方就创建好了。
三、gitee的api学习
文档:gitee的api文档
接口:
1、仓库->新建文件的api接口
2、仓库->删除文件的api接口
3、仓库->获取仓库具体路径下的信息的api接口
字段说明
1、新建文件的api接口(post请求)
**access_token :**这个access_token就是指我们上面申请的私人令牌。
**owner :**就是你码云账号的名称
repo : 就是上面创建的仓库名称
**path :**就是文件路径
**content :**文件内容,这里注意 文档上说明内容必须是以Base64编码的,这就意味着内容不能太大
**message :**提交信息
使用接口的方式进行图片提交,提交后会返回提交内容的地址。地址就是我们使用的外链地址
2、获取仓库具体路径的内容(get请求)
**access_token :**这个access_token就是指我们上面申请的私人令牌。
**owner :**就是你码云账号的名称
repo : 就是上面创建的仓库名称
**path :**就是文件路径
接口查询了文件对应的信息,里面有删除文件需要使用的sha参数
3、删除文件的api接口(delete请求)
**access_token :**这个access_token就是指我们上面申请的私人令牌。
**owner :**就是你码云账号的名称
repo : 就是上面创建的仓库名称
**path :**就是文件路径
**sha:**文件的 Blob SHA,可通过 [获取仓库具体路径下的内容] API 获取
**message :**提交信息
四、代码编写
代码使用的springboot进行编写,比较搭建起来快,方便。
引入主要依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.3</version>
</dependency>
2、正文代码:
package com.mark.mark1024.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.mark.mark1024.vo.R;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;import java.util.Date;
import java.util.HashMap;import java.util.Map;
/* * gitee图床工具类 * * */
@Component
public class GiteeBucketUtil {
/**
* TODO:这个常量是码云为您分配的私人令牌,Token
*/
@Value("${gitee.giteebucket.access-token}")
private String ACCESS_TOKEN;
/**
* 仓库所属地址 这个是您的私人用户名 具体请参考创建仓库时的注意事项
*/
@Value("${gitee.giteebucket.owner}")
private String OWNER;
/**
* TODO:仓库名称 这里是您的仓库名称
*/
@Value("${gitee.giteebucket.repo-name}")
private String REPO_NAME;
/**
* TODO:上传图片的message
*/
@Value("${gitee.giteebucket.create-repos-message}")
private String CREATE_REPOS_MESSAGE;
@Value("${gitee.giteebucket.remove-repos-message}")
private String REMOVE_REPOS_MESSAGE;
/**
* TODO:文件前缀 这里格式化咱们上传图片的路径,在img路劲下 以每天的日期为子文件夹,进行存储。 上传地址可以自定义。
*/
private static final String IMG_FILE_DEST_PATH = "img/" + DateUtil.format(new Date(), "yyyy_MM_dd") + "/";
private Logger logger = LoggerFactory.getLogger(GiteeBucketUtil.class);
/**
* 新建文件(请求方式POST)
* <p>
* owner* 仓库所属空间地址(企业、组织或个人的地址path)
* repo* 仓库路径
* path* 文件的路径
* content* 文件内容, 要用 base64 编码
* message* 提交信息
* <p>
* %s =>仓库所属空间地址(企业、组织或个人的地址path) (owner)
* %s => 仓库路径(repo)
* %s => 文件的路径(path)
*/
private static final String CREATE_REPOS_URL = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";
/**
* 删除一个文件(请求方式DELETE):https://gitee.com/api/v5/repos/{owner}/{repo}/contents/{path}
*/
private static final String REMOVE_REPOS_URL = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";
/**
* 获取仓库下具体的文件信息(请求方式GET):https://gitee.com/api/v5/repos/{owner}/{repo}/contents(/{path})
*/
private static final String GET_FILE_INFO_URL= "https://gitee.com/api/v5/repos/%s/%s/contents(/%s)";
public R uploadImg(MultipartFile file) throws IOException {
if (ObjectUtils.isEmpty(file)) {
return R.error("请重新上传!");
}
String trueFileName = file.getOriginalFilename();
assert trueFileName != null;
String suffix = trueFileName.substring(trueFileName.lastIndexOf("."));
String fileName = System.currentTimeMillis() + "_" + IdUtil.randomUUID() + suffix;
String paramImgFile = Base64.encode(file.getBytes());
//转存到gitee
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("access_token", ACCESS_TOKEN);
paramMap.put("message", CREATE_REPOS_MESSAGE);
paramMap.put("content", paramImgFile);
String targetDir = IMG_FILE_DEST_PATH + fileName;
String requestUrl = String.format(CREATE_REPOS_URL, OWNER, REPO_NAME, targetDir);
long startTime = System.currentTimeMillis();
String resultJson = HttpUtil.post(requestUrl, paramMap);
long endTime = System.currentTimeMillis();
logger.info("图片上传时间为:{}", (endTime - startTime));
JSONObject jsonObject = JSONUtil.parseObj(resultJson);
if (jsonObject.getObj("commit") != null) {
JSONObject content = jsonObject.getJSONObject("content");
String download_url = content.getStr("download_url");
return R.ok().data("url", download_url);
} else {
return R.error("上传失败!"+ resultJson);
}
}
/**
* 删除文件
* @param filePath 文件路径
* @return
*/
public R removeFile(String filePath) {
if (ObjectUtils.isEmpty(filePath)) {
return R.error("文件路径不能为空");
}
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("access_token", ACCESS_TOKEN);
String requestUrl = String.format(CREATE_REPOS_URL, OWNER, REPO_NAME, filePath);
JSONObject fileInfoObject = getFileInfo(filePath);
if (fileInfoObject == null || StringUtils.isBlank(fileInfoObject.getStr("sha"))) {
return R.ok();
}
paramMap.put("message", REMOVE_REPOS_MESSAGE);
paramMap.put("sha", fileInfoObject.getStr("sha"));
long startTime = System.currentTimeMillis();
HttpRequest request = HttpUtil.createRequest(Method.DELETE, requestUrl);
String resultStr = request.form(paramMap).timeout(3000).execute().body();
long endTime = System.currentTimeMillis();
logger.info("文件删除时间为:{}", (endTime - startTime));
JSONObject jsonObject = JSONUtil.parseObj(resultStr);
if (jsonObject.getObj("commit") != null) {
return R.ok().data("msg", "删除成功");
} else {
return R.error("删除文件失败!"+ resultStr);
}
}
/**
* 获取文件的信息
* @param filePath 文件路径
* @return
*/
public JSONObject getFileInfo(String filePath) {
if (ObjectUtils.isEmpty(filePath)) {
return null;
}
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("access_token", ACCESS_TOKEN);
String requestUrl = String.format(CREATE_REPOS_URL, OWNER, REPO_NAME, filePath);
long startTime = System.currentTimeMillis();
String fileInfo = HttpUtil.get(requestUrl, paramMap);
long endTime = System.currentTimeMillis();
logger.info("获取文件的信息的时间为:{}", (endTime - startTime));
if("[]".equals(fileInfo)) {
return null;
}
JSONObject fileInfoObject = JSONUtil.parseObj(fileInfo);
return fileInfoObject;
}
}
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据
*
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
controller控制类:
@PostMapping("/upload")
public R upload(@RequestParam(value = "file",required = true) MultipartFile file) {
try {
return giteeBucketUtil.uploadImg(file);
}catch (Exception e) {
e.printStackTrace();
logger.error("图片上传失败,{}",file.getOriginalFilename());
}
return R.error();
}
@PostMapping("/removeFile")
public R removeFile(@RequestParam(value = "filePath",required = true) String filePath) {
try {
return giteeBucketUtil.removeFile(filePath);
}catch (Exception e) {
e.printStackTrace();
logger.error("图片上传失败,{}", filePath);
}
return R.error();
}
上面就是利用gitee图床的搭建和使用了,不仅可以放图片,还可以放置其他文件,上面代码如有不对请指教
最近做了个程序员导航栏,做完后,到时候给大家用用。
文字由作者原创,图片部分来源于网络,版权归原作者所有。
关注公#@众#@号,有大波福利持续更新哦,正规福利