在网上没有找到java版的向github仓库上传文件的工具,于是便自己查api封装一个
为了方便我们可以通过代码执行上传相应文件到github指定仓库,做实时的公共文档或图片存储,github给我们提供一个便利的方式,通过api即可实现文件的上传查询和删除等操作,当时用github存图片时一直没有找到java版本封装好的类库,于是决定自己一边查资料一边巩固自学的java知识,封装一个;
一 申请令牌(github token)
在github登录成功后,点击此处直接跳转到token申请页面,或通过用户头像->Settings-> Developer settings->Personal access tokens-> Tokens (classic):
点击 Generate new token创建新的token,并根据自己的实际情况输入token描述,时间以及权限,权限至少勾选repo:
点击最下方的Generate token生成token,注意token只显示一次,记得记录保存好:
二 查阅github的api文档
点击此处跳转到官方文档,查阅api的调用方式.简单来说,github采用普通的http方式来实现文件的查询,新增和删除,在这里,我们只针对新增进行封装;
点击create-or-update-file-contents直接查看文件上传的api.
我们可以看到一个非常简单的例子,通过put请求,将进行好base64编码的内容上传到仓库中,
/repos/"+username[用户名]+"/"+depository[仓库名]+"/contents/"+fileName[路径及文件名];
既然该有的我们都有了,接下来我们准备封装工具类
三 使用java封装
1 配置项
在项目工程的resources文件夹下配置yml文件:
githubclub:
config:
username: tangyuxian #用户名
token: #token填写在这里
depository: blog_image #仓库名
message: fromJavaServe #描述
domain: https://cdn.jsdelivr.net/gh/tangyuxian/blog_image@latest #cdn加速域名
2 封装工具类
1) HttpUtils.java
这个工具类用于创建http请求
public class HttpUtils {
private CloseableHttpClient httpClient;
/**
* 与Spring集成初始化HttpClient
* 在Spring启动后会调用init方法
*/
@PostConstruct
public void init() {
httpClient = HttpClients.custom().build();
}
/**
* application-json方式提交
* @param url http路径
* @param json json字符串 {"key":"value"}
* @return 响应内容字符串
*/
public String postJson(String url, String json) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
try(CloseableHttpResponse response = httpClient.execute(httpPost)) {
return EntityUtils.toString( response.getEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* application/x-www-form-urlencoded 方式提交
* @param url http路径
* @param kvMap key与value组成的map
* @return 响应内容字符串
*/
public String postForm(String url, Map<String, String> kvMap) {
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nvps = new ArrayList<>();
kvMap.forEach((key, value) -> nvps.add(new BasicNameValuePair(key, value)));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
try(CloseableHttpResponse response = httpClient.execute(httpPost)) {
return EntityUtils.toString(response.getEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* get请求
* @param url http路径 (后可跟参数?p1=aaa&p2=bbb&p3=ccc)
* @return 响应内容字符串
*/
public String getString(String url) {
HttpGet httpget = new HttpGet(url);
try(CloseableHttpResponse response = httpClient.execute(httpget)) {
return EntityUtils.toString(response.getEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* get请求
* @param url http路径 (后可跟参数?p1=aaa&p2=bbb&p3=ccc)
* @return 响应内容
*/
public byte[] getBytes(String url) {
HttpGet httpget = new HttpGet(url);
try(CloseableHttpResponse response = httpClient.execute(httpget)) {
return EntityUtils.toByteArray(response.getEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* application-json方式提交
* @param url http路径
* @param json json字符串 {"key":"value"}
* @return 响应内容字符串
*/
public String putJson(String url, String json,Map<String, String> headerMap) {
HttpPut httpPut = new HttpPut(url);
headerMap.entrySet().forEach(entry->httpPut.addHeader(entry.getKey(), entry.getValue()));
httpPut.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
try(CloseableHttpResponse response = httpClient.execute(httpPut)) {
return EntityUtils.toString( response.getEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 与Spring集成销毁HttpClient
* 在Spring关闭后会调用destroy方法
*/
@PreDestroy
public void destroy() throws Exception {
httpClient.close();
}
}
2) GithubClubUtil.java
这个工具类用来封装文件上传功能
@Component
@ConfigurationProperties(prefix = "githubclub.config")
public class GithubClubUtil {
@Autowired
HttpUtils httpUtils;
/**
* 用户名
*/
private String username;
/**
* token
*/
private String token;
/**
* 仓库名
*/
private String depository;
/**
* 统一提交信息
*/
private String message;
/**
* 自定义域名
*/
private String domain;
private String GITHUBAPI = "https://api.github.com";
/**
* 文件推送到github
* @param fileName 文件名
* @param content json 数据格式 {"message":"test commit","content":"bXkgbmV3IGZpbGUgY29udGVudHM="}
* @return
*/
public HashMap<String, Object> contentFile(String fileName, String content){
String url = GITHUBAPI + "/repos/"+username+"/"+depository+"/contents/"+fileName;
HashMap<String, String> header = new HashMap<>();
header.put("Authorization","token "+token);
header.put("Accept","Accept: application/vnd.github.v3+json");
String json = "{\"message\":\""+message+"\",\"content\":\""+content+"\"}";
String res = httpUtils.putJson(url, json, header);
return filterResultForContentFile(res,fileName);
}
/**
* 处理调用接口后返回的值
* @param res
* @param fileName
* @return
*/
private HashMap<String,Object> filterResultForContentFile(String res,String fileName){
Map<String, Object> map = JsonUtil.jsonToMap(res);
Map<String, Object> commit = (Map<String, Object>) map.get("commit");
HashMap<String, Object> result = new HashMap<>();
if(commit.get("message").equals(message)){
result.put("success",true);
result.put("data",domain+fileName);
}else{
result.put("success",false);
}
return result;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getDepository() {
return depository;
}
public void setDepository(String depository) {
this.depository = depository;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
}
3) GithubClubConfig.java
配置信息注入到Bean中
public class GithubClubConfig {
@Bean
public GithubClubUtil githubClubUtil(){return new GithubClubUtil();}
}
3 测试工具类
1) 测试下是否可用
@GetMapping("/uploadFile")
public R uploadFile(){
String fileName = "test/test3.txt";
String content = "bXkgbmV3IGZpbGUgY29udGVudHM=";
HashMap map = githubClubUtil.contentFile(fileName,content);
if((Boolean)map.get("success")){
return R.ok();
}else{
return R.err();
}
}
2) 提供一个文件上传的方法
具体细节根据自己实际情况进一步封装即可
@PostMapping("/upload")
public R uploadOld(@RequestParam("file") MultipartFile file) {
System.out.println(file.getOriginalFilename());
System.out.println(file.getName());
System.out.println(file.getContentType());
String name = file.getOriginalFilename();
String sname =name.substring(name.lastIndexOf("."));
String fileName = "/test/"+"tyx_"+ RandomStringUtils.getRandomString(10)+sname;
Base64 base64Encoder = new Base64();
byte[] imageBytes = null;
String base64EncoderImg="";
try{
imageBytes = file.getBytes();
base64EncoderImg = base64Encoder.encodeToString(imageBytes);
HashMap map = githubClubUtil.contentFile(fileName,base64EncoderImg);
if((Boolean)map.get("success")){
return R.ok(map.get("data"));
}else{
return R.err();
}
}catch (Exception e){
throw new RuntimeException(e);
}
}
大功告成啦!