1.概述
Gitlab作为一个开源、强大的分布式版本控制系统,已经成为互联网公司、软件开发公司的主流版本管理工具。使用过Gitlab的都知道,想要提交一段代码,可以通过git push提交到远程仓库,也可以直接在Gitlab平台上修改提交。然而上述两种提交方式都是人工提交代码,需要手动登录Gitlab或者在第一次commit的时候提供Gitlab帐号和密码。
那么,假设有这么一个需求场景:我们开发了一个效率平台,可以自动拉分支、自动提交代码到远程仓库。这个需求该如何实现?其实很简单,Gitlab提供了一套完整的API,让第三方平台可以通过API自动创建帐号、自动提交代码、自动拉分支,等等。API涉及到的功能非常全面,覆盖了分支、tag、代码提交、用户、群组、项目等,基本上人工可以做的所有操作,都可以通过API自动实现。
Gitlab的Api的文档入口为http://{gitlab_host}/help/api/README.md
2.技术要点
Gitlab本质上也是一个web服务器,Gitlab官方提供了一个非常完整的restful API,我们可以使用apache开发的一个工具包HttpClient,HttpClient可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
当我们想要执行某种操作时,我们只需要在Gitlab的api文档上查找到对应的路径,然后在自己的后台利用HttpClient将对应的链接发送至Gitlab服务器即可,HttpClient功能非常强大,支持get,post,put,delete等七种请求方式。
附录一个讲解HttpClient非常完善的链接:http://www.yeetrack.com/?p=779;
3.使用HttpClient完成一次请求
使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
1.创建HttpClient对象。
2.创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3.如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
4.调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
5.调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
6.释放连接。无论执行方法是否成功,都必须释放连接。
Get请求使用方法:
public static String httpGet(String url) throws Exception {
CloseableHttpClient httpclients = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpclients.execute(httpGet);
HttpEntity httpEntity = response.getEntity();
try{
HttpEntity entity = response.getEntity();
if(entity != null) {
InputStream is = entity.getContent();
}
}finally{
response.close();
}
return EntityUtils.toString(httpEntity,"UTF-8");
}
Post请求示例如下:
public static String httpPost(String url,List<NameValuePair> formparams) throws Exception {
CloseableHttpClient httpclients = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,Consts.UTF_8);
httpPost.setEntity(entity);
CloseableHttpResponse response = httpclients.execute(httpPost);
HttpEntity entity1 = response.getEntity();
try{
HttpEntity entity5 = response.getEntity();
if(entity != null) {
InputStream is = entity.getContent();
}
}finally{
response.close();
}
return EntityUtils.toString(entity1);
}
4.身份认证
Gitlab的所有API都需要提供private_token参数进行用户身份认证(除了用来获得private_token的接口本身)。如果没有提供或者提供的private_token不合法,API将会返回401错误码。如下:
{"message":"401 Unauthorized"}
private_token是用来代表用户身份的字符串,和用户是一一对应的关系,http请求中包含这个可以免输入用户名和密码。
获得private_token的方式有两种:
方法一:查看帐号设置(Profile Settings->Account)。如下图:
方法二:通过Session API获得Gitlab提供了一个API获取某个用户对应的private_token,这样就能把操作的都完全自动化起来,也方便Gitlab与其它系统/平台打通。Session接口需要提供帐号密码来进行身份认证。
示例如下:
5.操作Gitlab的实例
@Test
//新建项目
public void post1() throws Exception {
String url = "http://192.168.124.46/api/v3/projects";
List<NameValuePair> formparams = new ArrayList <NameValuePair>();
//新建项目大约有20个参数可以设置
formparams.add(new BasicNameValuePair("private_token", "2W6HbdQc4NuVbgTaz1hW"));
formparams.add(new BasicNameValuePair("private_token", "rTRdYCbqDpPNxttpE8ox"));
formparams.add(new BasicNameValuePair("email", "643216160@qq.com"));
formparams.add(new BasicNameValuePair("password", "aaaasasasas"));
formparams.add(new BasicNameValuePair("reset_password", "true"));
formparams.add(new BasicNameValuePair("username", "lishuwang"));
formparams.add(new BasicNameValuePair("name", "wangzai"));
formparams.add(new BasicNameValuePair("skype", "qwqw"));
formparams.add(new BasicNameValuePair("linkedin", "qwwq"));
System.out.println(Utils.httpPost(url, formparams));
}
//查询当前用户的某个项目
@Test
public void httpGet2() throws Exception {
//变量为项目id
String url = "http://192.168.121.215/api/v3/projects/49?private_token=L9C8yBBwYxvRBxLxF2ge";
String entity = Utils.httpGet(url);
System.out.println(entity);
}
6.总结
对Gitlab进行二次开发实际上就是通过HttpClient工具类来代替我们发送请求给Gitlab服务器,而不需要我们自己再手动访问Gitlab网页来进行操作。原理和思路并不难理解。其中要注意的就是使用HttpClient发送请求时需要携带一个private_token的参数过去,每个用户都有一个唯一的私人令牌,此令牌作为用户的唯一标识,Gitlab给我们提供了一个通过用户名和密码来专门获取此private_token的api,当然身份验证的方式不仅仅有这一种,还有OAuth2令牌和个人访问令牌的方式都可以。