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"}
- 1
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令牌和個人訪問令牌的方式都可以。