这样免费白嫖的图床,给你们,你们要吗

627 阅读5分钟

乐享精致生活 Enjoy a fine life

846.jpg

有爱的人终会在路口相遇、相拥、相伴

如何利用gitee搭建免费的图床,并且实现上传和下载

一、那些年的“执念”

前两天我们做了个网站,因为是个人的,图片存储是个问题,不想发到自己的服务器上占内存(钱有限),想着利用别人的免费图床,这个省了空间和钱,于是我找了很多,发现很多图床都有限制,比较是免费给你使用,不可能没有限制,毕竟没人这么有钱给你这样霍霍,而且,我们是那种白嫖的人吗?当然不(jiu)是(shi),我只是想给大伙某份福利,给大伙寻一免费的图床,终于找到了满足你们需求的图床,而且不会有图片丢失的风险(除非你偷偷把它删除了),那什么可以做免费图床呢,gitee,github都用过吧,其实应该都可,但是github毕竟是外国网站,访问太慢太受限了,所以我就选择了gitee

4545.jpg图片|来源于网络

二、环境准备

1、注册一个gitee账号,然后登录

2、进入设置(设置知道怎么进入吧,不知道?对就是那样进入的)

3、找到 私人令牌,然后生成令牌

1.png

2.png

4、接着在gitee上创建一个 公开 的仓库3.png4.png5.png

到这里图片存储的地方就创建好了。

三、gitee的api学习

文档:gitee的api文档

接口:

1、仓库->新建文件的api接口

2、仓库->删除文件的api接口

3、仓库->获取仓库具体路径下的信息的api接口

字段说明

1、新建文件的api接口(post请求)

**access_token :**这个access_token就是指我们上面申请的私人令牌。

**owner :**就是你码云账号的名称

repo : 就是上面创建的仓库名称

6.png

**path :**就是文件路径

7.png

**content :**文件内容,这里注意 文档上说明内容必须是以Base64编码的,这就意味着内容不能太大

**message :**提交信息

使用接口的方式进行图片提交,提交后会返回提交内容的地址。地址就是我们使用的外链地址

2、获取仓库具体路径的内容(get请求)

**access_token :**这个access_token就是指我们上面申请的私人令牌。

**owner :**就是你码云账号的名称

repo : 就是上面创建的仓库名称

**path :**就是文件路径

7.png

接口查询了文件对应的信息,里面有删除文件需要使用的sha参数

3、删除文件的api接口(delete请求)

**access_token :**这个access_token就是指我们上面申请的私人令牌。

**owner :**就是你码云账号的名称

repo : 就是上面创建的仓库名称

**path :**就是文件路径

7.png

**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图床的搭建和使用了,不仅可以放图片,还可以放置其他文件,上面代码如有不对请指教

最近做了个程序员导航栏,做完后,到时候给大家用用。

文字由作者原创,图片部分来源于网络,版权归原作者所有。

关注公#@众#@号,有大波福利持续更新哦,正规福利