GitHub Rest API文档:https://docs.github.com/zh/rest/repos/contents?apiVersion=2022-11-28#create-or-update-file-contents
1. 配置 GitHub
1. 注册GitHub 账号
GitHub官网地址:https://github.com/
2. 创建仓库,点击右上角的+号,点击 New repository
3. 填写仓库信息
4. 点击右上角的头像,打开 Settings
5. 选择左侧菜单的 Developer settings
6. 点击 Personal access tokens -> Tokens (classic) -> Generate new token -> Generate new token(classic)
7. 填写 Note,勾选 repo,Expiration 指的是有效时间,根据自己的需求来选择
8. 点击生成按钮 Generate token 生成 token ,注意 token 只显示一次,记得记录保存好
2. Sping Boot 项目配置
1. application.yml
Github:branch: xxxxxx # 上传到仓库的分支名name: xxxxx # 提交者的用户名email: [email protected] # 提交者的邮箱message: xxxxxx # 提交信息OWNER: xxxxx # 仓库的所有者,名称不区分大小写,GitHub的账户名称REPO: xxxxx # 仓库名称Authorization: xxxxx # 填写上面申请的token
2. GitHubController 文件
importorg.springframework.beans.factory.annotation.Value;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.net.HttpURLConnection;importjava.net.URL;importjava.net.URLEncoder;importjava.nio.file.Files;importjava.nio.file.Paths;importjava.util.Base64;@RestController@RequestMapping("/github")publicclassGithubController{@Value("${Github.branch}")privateString branch;// Github 仓库的分支@Value("${Github.name}")privateString committerName;// 提交者的姓名@Value("${Github.email}")privateString committerEmail;// 提交者的邮箱@Value("${Github.message}")privateString commitMessage;// 提交的消息@Value("${Github.OWNER}")privateString owner;// Github 仓库的所有者@Value("${Github.REPO}")privateString repo;// Github 仓库的名称@Value("${Github.Authorization}")privateString token;// Github 个人访问令牌/**
* 上传文件到Github仓库
*
* @param filePath 文件在仓库中的路径
* @param content 文件内容,要上传文件的路径
* @return ApiResponse 包含上传结果信息的响应
* @throws IOException IO异常
*/@GetMapping("/upload")publicApiResponseupload(@RequestParamString filePath,@RequestParamString content)throwsIOException{// 对路径进行URL编码String path =URLEncoder.encode(filePath,"UTF-8");System.out.println(path);// 将内容进行Base64编码String contents =encryptToBase64(content);// 构建Github API的URLString apiUrl =String.format("https://api.github.com/repos/%s/%s/contents/%s", owner, repo, path);// 构建基本认证头部String basicAuth =Base64.getEncoder().encodeToString((token +":").getBytes());String authorizationHeader ="Basic "+ basicAuth;// 构建请求体String requestBody =String.format("{\"message\":\"%s\", \"branch\":\"%s\", \"committer\":{\"name\":\"%s\", \"email\":\"%s\"}, \"content\":\"%s\"}",
commitMessage, branch, committerName, committerEmail, contents
);// 构建并发送HTTP PUT请求URL url =newURL(apiUrl);HttpURLConnection connection =(HttpURLConnection) url.openConnection();
connection.setRequestMethod("PUT");
connection.setRequestProperty("Authorization", authorizationHeader);
connection.setRequestProperty("Content-Type","application/json");
connection.setRequestProperty("Accept","application/vnd.github.v3+json");
connection.setDoOutput(true);// 写入请求体
connection.getOutputStream().write(requestBody.getBytes("UTF-8"));// 读取响应try(BufferedReader reader =newBufferedReader(newInputStreamReader(connection.getInputStream()))){String line;StringBuilder response =newStringBuilder();while((line = reader.readLine())!=null){
response.append(line);}// 打印响应System.out.println("Response Code: "+ connection.getResponseCode());System.out.println("Response Body: "+ response.toString());// 解析响应获取 download_url// String downloadUrl = parseDownloadUrl(response.toString());// 通过 cdn 加速的 download_urlString downloadUrl ="https://cdn.jsdelivr.net/gh/"+owner+"/"+repo+"/"+path;returnApiResponse.ok(downloadUrl,"上传成功");}finally{
connection.disconnect();}}/**
* 解析Github API响应中的 download_url
*
* @param jsonResponse Github API的JSON响应
* @return download_url
*/privatestaticStringparseDownloadUrl(String jsonResponse){int startIndex = jsonResponse.indexOf("\"download_url\":\"")+16;int endIndex = jsonResponse.indexOf("\"", startIndex);return jsonResponse.substring(startIndex, endIndex);}/**
* 将内容进行Base64编码
*
* @param content 原始内容
* @return Base64编码后的内容
*/privateStringencryptToBase64(String content)throwsIOException{returnBase64.getEncoder().encodeToString(Files.readAllBytes(Paths.get(content)));}}
3. 注意事项:
问题:SSL 证书验证错误
错误信息:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
解决方法:导入GitHub SSL证书
- 获取 GitHub 证书: 使用 openssl 工具获取 GitHub 的 SSL 证书
echo| openssl s_client -showcerts-connect github.com:443 2>/nul | openssl x509 > github.crt
- 导入证书到 Java TrustStore: 使用 keytool 命令将证书导入 Java 的信任存储库
keytool -import-alias github -keystore"C:\Program Files\Java\jdk<version>\jre\lib\security\cacerts"-file path\to\save\directory\github.crt
替换
<version>
为Java版本号,
path\to\save\directory
为保存证书的目录
- 如果需要输入
keystore
密码,则输入changeit
- 重新运行
Java
程序,看看是否解决了 “PKIX path building failed” 错误。请注意,这是一种快速的解决方案,但在生产环境中,请使用受信任的证书颁发机构(CA)签署的 SSL 证书以确保通信的安全性。
版权归原作者 -沐云枫- 所有, 如有侵权,请联系我们删除。