之前写过一篇帖子,GitHub + jsDelivr CDN 全球加速的免费图床,它不香吗? 这篇帖子中,使用的是桌面客户端 PicGo,进行图片上传的。在这里我们使用SpringBoot中的RestTemplate作为客户端,上传文件到Github仓库。
参考上面的帖子,这里不再重复讲诉。
github: bucket: # 配置仓库所属的用户名(如果是自己创建的,就是自己的用户名) user: "springboot-community" # 配置仓库名称 repository: "twitter-bucket" # 配置自己的acccessToken access-token: "996e748cb47117adbf3**********" url: "https://cdn.jsdelivr.net/gh/${github.bucket.user}/${github.bucket.repository}/" api: "https://api.github.com/repos/${github.bucket.user}/${github.bucket.repository}/contents/"
你只需要配置好,上面自己有注释的3个配置就OK了
封装的一个工具类,根据上面的配置进行文件的上传
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; @Component public class GithubUploader { private static final Logger LOGGER = LoggerFactory.getLogger(GithubUploader.class); public static final String URI_SEPARATOR = "/"; public static final Set<String> ALLOW_FILE_SUFFIX = new HashSet<> (Arrays.asList("jpg", "png", "jpeg", "gif")); @Value("${github.bucket.url}") private String url; @Value("${github.bucket.api}") private String api; @Value("${github.bucket.access-token}") private String accessToken; @Autowired RestTemplate restTemplate; /** * 上传文件到Github * @param multipartFile * @return 文件的访问地址 * @throws IOException */ public String upload (MultipartFile multipartFile) throws IOException { String suffix = this.getSuffix(multipartFile.getOriginalFilename()).toLowerCase(); if (!ALLOW_FILE_SUFFIX.contains(suffix)) { throw new IllegalArgumentException("不支持的文件后缀:" + suffix); } // 重命名文件 String fileName = UUID.randomUUID().toString().replace("-", "") + "." + suffix; // 目录按照日期打散 String[] folders = this.getDateFolder(); // 最终的文件路径 String filePath = new StringBuilder(String.join(URI_SEPARATOR, folders)).append(fileName).toString(); LOGGER.info("上传文件到Github:{}", filePath); JsonObject payload = new JsonObject(); payload.add("message", new JsonPrimitive("file upload")); payload.add("content", new JsonPrimitive(Base64.getEncoder().encodeToString(multipartFile.getBytes()))); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); httpHeaders.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); httpHeaders.set(HttpHeaders.AUTHORIZATION, "token " + this.accessToken); ResponseEntity<String> responseEntity = this.restTemplate.exchange(this.api + filePath, HttpMethod.PUT, new HttpEntity<String>(payload.toString(), httpHeaders), String.class); if (responseEntity.getStatusCode().isError()) { // TODO 上传失败 } JsonObject response = JsonParser.parseString(responseEntity.getBody()).getAsJsonObject(); LOGGER.info("上传完毕: {}", response.toString()); // TODO 序列化到磁盘备份 return this.url + filePath; } /** * 获取文件的后缀 * @param fileName * @return */ protected String getSuffix(String fileName) { int index = fileName.lastIndexOf("."); if (index != -1) { String suffix = fileName.substring(index + 1); if (!suffix.isEmpty()) { return suffix; } } throw new IllegalArgumentException("非法的文件名称:" + fileName); } /** * 按照年月日获取打散的打散目录 * yyyy/mmd/dd * @return */ protected String[] getDateFolder() { String[] retVal = new String[3]; LocalDate localDate = LocalDate.now(); retVal[0] = localDate.getYear() + ""; int month = localDate.getMonthValue(); retVal[1] = month < 10 ? "0" + month : month + ""; int day = localDate.getDayOfMonth(); retVal[2] = day < 10 ? "0" + day : day + ""; return retVal; } }
import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import io.springboot.twitter.common.Message; import io.springboot.twitter.github.GithubUploader; @RestController @RequestMapping("/upload") public class UploadController { @Autowired private GithubUploader githubUploader; @PostMapping public Object upload (@RequestParam("file") MultipartFile multipartFile) throws IOException { return Message.success(this.githubUploader.upload(multipartFile)); } }
通过CDN访问上传后的文件 😍https://cdn.jsdelivr.net/gh/springboot-community/twitter-bucket/2020/06/169e652259a03b42f382433fb4481263d4.gif