如何在spring boot 使用 gitlab的Api

weiewiyi發表於2022-07-19

前言

最近有專案需求是通過gitlab的api獲取其中的資料。來記錄一下我的踩坑的過程。
首先先嚐試了獲取users資料,即所有使用者的資料。

這裡是gitlab官方API文件 https://docs.gitlab.com/ee/ap...

這裡說一下我剛開始的做法和老師建議的做法。

最開始的做法

1. 獲取Admin access token

首先我們需要獲取gitlab的Admin access token, 並且在請求的時候附帶這個token,gitlab才能認證我們的身份並返回資料。

1.登入 GitLab。 2.登入後,點選右上角的頭像圖示然後選擇 Preferences。

3.在 access token 介面就可以新建token了。

當你是group的管理員之後,就可以通過該token獲取users了。

2.使用spring boot單元測試發起請求

這裡我使用了apache發起http請求,並使用了fastjson處理請求後所返回的json資料。

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.9</version>
</dependency>

 <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

以下是我測試的程式碼。來解釋一下:

  1. 首先定義你的要請求的url,格式如程式碼。也可以看官方文件。
  2. 構建Http請求類,並設定引數。引數必須要有private_token。這裡我加的 without_project_bots可以過濾機器人user。
  3. 使用execute函式發起get請求,並接收返回的json資料。
  4. 從json陣列轉換成實體陣列

這樣就獲得了我們需要的資料。

@Test
  void getUsers() throws IOException, URISyntaxException {

    String url = "https://your gitlab address/api/v4/users";


    CloseableHttpClient httpclients = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet(url);
    // 設定引數資訊
    URI uri = new URIBuilder(httpGet.getURI())
            .addParameter("private_token", "your amind token")
            .addParameter("without_project_bots", "true")
            .build();
    ((HttpRequestBase) httpGet).setURI(uri);

    // 發起請求
    CloseableHttpResponse response = httpclients.execute(httpGet);

    // 處理資料
    HttpEntity httpEntity = (HttpEntity) response.getEntity();
    String result =  EntityUtils.toString(httpEntity,"UTF-8");

    // 從json轉換成實體
    final ObjectMapper objectMapper = new ObjectMapper();
    User[] langList = objectMapper.readValue(result, User[].class);

    logger.debug(String.valueOf(langList));

    response.close();
  }

期間我遇到的問題

1. java需要新增證照

由於我們發起的請求地址是HTTPS的,而https是對連結加了安全證照SSL的。
對方的介面需要特定的證照才能請求。如果伺服器中沒有相關連結的SSL證照,就會報sun.security.validator.ValidatorException錯誤。

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

最開始我是把證照新增到本地中的,新增方法大概參考瞭如下部落格
https://www.cnblogs.com/zoro-...

這樣就把證照新增到了本地的java金鑰庫中。

但是這樣只有本地能夠正常使用這個專案。因為在並沒有把證照新增到專案中。所以這也說明了這種方法並不普適。

所以我們需要把證照放在src/main/resourse中,部署https。下面我會說一下如何新增。

2. 沒有配置資料來源

Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]

image.png

由於我只是在單元測試中測試,專案剛初始化,並沒有連線資料庫,也就是並沒有配置資料來源。

所以因為沒有向 Spring Boot 傳遞足夠的資料來配置資料來源,導致發生了該報錯。

所以,如果我們暫時不需要資料來源,就可以使用exclude={DataSourceAutoConfiguration.class}自動配置。 這樣就可以解決報錯

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class NonlycodeApplication {
}

3. json資料的屬性多於實體的屬性

在我請求到資料後,可以看到gitlab給我們返回來的資料有很多。有theme_id, note,is_admin等資訊。
image.png


但是, 我定義的實體中目前只定義了幾條需要的資訊,比如id ,name,username等資訊。

public class User implements Serializable {

  private static final long serialVersionUID = 1L;

  @Id
  private Long id;

  private String email = "";

  private Integer following = 0;

  private Integer followers = 0;

  private String name = "";

  private  String password = "yunzhi";

  @Column(nullable = false, unique = true)
  private String username;

在json轉化資料的時候,遇到這種情況就會報錯。並且報錯說:not marked as ignorable。
image.png

所以我們需要新增註釋,把不需要的資料給忽略掉。

我的解決方法是新增 @JsonIgnoreProperties(ignoreUnknown = true)
最後報錯消失。

@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
public class User implements Serializable {

使用RestTemplate通過證照認證訪問https

傳統情況下在java程式碼裡訪問restful服務,一般使用Apache的HttpClient。如同我上面的程式碼。不過此種方法使用起來太過繁瑣。spring提供了一種簡單便捷的模板類來進行操作,這就是RestTemplate。

1. 獲取證照

我參考了這篇文章來生成自簽名證照。
https://www.baeldung.com/spri...

或者可以下載網站的證照,參考這篇文章來操作
https://fullstackdeveloper.gu...

把生成的檔案匯入到專案resourses/keystore中
image.png

2. 配置application.yml

填寫一下自己配置的password和alias別名等

server:
  ssl:
    key-store-type: PKCS12
    key-store: classpath:keystore/baeldung.p12
    key-store-password: changeit
    key-alias: baeldung
  port: 8443

spring:
  security:
    user:
      name: root
      password: 1234

4. 配置restTemplate

配置restTemplate,使其載入專案中的證照

  1. 新建CustomConfiguration類
    image.png
  2. 重寫restTemplate()函式

注意一下自己的檔名,以及剛才自己設定的key-store密碼

@Configuration
public class CustomConfiguration {

  @Bean
  RestTemplate restTemplate() throws Exception {
    SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(new URL("file:src/main/resources/keystore/baeldung.p12"), "changeit".toCharArray()).build();
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
    HttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(socketFactory)
            .build();
    HttpComponentsClientHttpRequestFactory factory =
            new HttpComponentsClientHttpRequestFactory(httpClient);
    return new RestTemplate(factory);
  }
}

3. 編寫程式碼

controller層:

@RestController
@RequestMapping("user")
public class UserController {

  @Autowired
  UserService userService;


  @GetMapping("/getUsers")
  @JsonView(GetUsersJsonView.class)
  public User[] getUsers() throws JsonProcessingException {
    return  this.userService.getUsers();
  }

  public class GetUsersJsonView {
  }
}

service層:
注意填寫自己的url和token。 邏輯跟之前的程式碼差不多。

@Override
  public User[] getUsers() throws JsonProcessingException {
    String url = "https://your gitlab address /api/v4/users/" +
            "?private_token={private_token}&without_project_bots={without_project_bots}";

    final Map<String, String> variables = new HashMap<>();

    variables.put("private_token", "your token");
    variables.put("without_project_bots", "true");

    RestTemplate restTemplate = new RestTemplate();
    String response = restTemplate.getForObject(url, String.class, variables);


    // 從json轉換成實體
    final ObjectMapper objectMapper = new ObjectMapper();
    User[] userList = objectMapper.readValue(response, User[].class);

    return userList;
  }

4. url訪問

image.png

可能是因為spring security, 需要登入。 我們輸入application.yml中配置好的賬號密碼
image.png

5. 結果

可能是jsonView沒配置好,頁面顯示空資訊。之後再弄一下。
image.png

但是經過打斷點列印, 顯示成果獲取到了gitlab中的users資訊。
image.png

總結

經過這次對gitlab API的請求嘗試,感覺自己對如何進行請求、如何處理返回的json資料有了更深的理解。同時也感覺自己對https,以及SSL證照等的理解還不足,之後還需要補一下相關知識。

相關文章