美文网首页
在SpringBoot中通过RestTemplate提交文件到G

在SpringBoot中通过RestTemplate提交文件到G

作者: JonathanYee | 来源:发表于2020-06-16 22:04 被阅读0次

    在SpringBoot中通过RestTemplate提交文件到Github(白嫖图床)

    Github仓库 + jsDelivr = 全球加速的免费图床

    之前写过一篇帖子,GitHub + jsDelivr CDN 全球加速的免费图床,它不香吗? 这篇帖子中,使用的是桌面客户端 PicGo,进行图片上传的。在这里我们使用SpringBoot中的RestTemplate作为客户端,上传文件到Github仓库。

    先在Github中创建一个public的仓库,和AccessToken

    参考上面的帖子,这里不再重复讲诉。

    SpringBoot的yml文件中添加配置

    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了

    GithubUploaderGithubUploader

    封装的一个工具类,根据上面的配置进行文件的上传

    • 使用UUID重新命名文件,防止冲突
    • 根据日期打散目录:yyyy/mm/dd
    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;
        }
    }
    

    Controller

    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));
        }
    }
    

    测试OK

    图片.png

    通过CDN访问上传后的文件

    https://cdn.jsdelivr.net/gh/springboot-community/twitter-bucket/2020/06/169e652259a03b42f382433fb4481263d4.gif

    image

    相关文章

      网友评论

          本文标题:在SpringBoot中通过RestTemplate提交文件到G

          本文链接:https://www.haomeiwen.com/subject/bnjdxktx.html