Ръководство за Google-Http-клиент

1. Общ преглед

В тази статия ще разгледаме клиентската библиотека на Google HTTP за Java, която е бърза, добре абстрахирана библиотека за достъп до всякакви ресурси чрез протокола за HTTP връзка.

Основните характеристики на клиента са:

  • HTTP абстракционен слой, който ви позволява да отделите всяка библиотека от ниско ниво
  • бързи, ефективни и гъвкави JSON и XML модели за анализ на HTTP отговора и съдържанието на заявките
  • лесни за използване анотации и абстракции за съпоставяне на HTTP ресурси

Библиотеката може да се използва и в Java 5 и по-нови версии, което я прави значителен избор за наследствени проекти (SE и EE).

В тази статия ще разработим просто приложение, което ще се свърже с API на GitHub и ще извлича потребители , като същевременно обхваща някои от най-интересните функции на библиотеката.

2. Зависимости на Maven

За да използваме библиотеката, ще ни трябва зависимостта на google-http-client :

 com.google.http-client google-http-client 1.23.0 

Най-новата версия може да бъде намерена в Maven Central.

3. Подаване на проста заявка

Нека започнем, като направим проста GET заявка към страницата на GitHub, за да покажем как работи клиентът на Google Http:

HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory(); HttpRequest request = requestFactory.buildGetRequest( new GenericUrl("//github.com")); String rawResponse = request.execute().parseAsString()

За да направим най-простата заявка, ще ни трябва поне:

  • HttpRequestFactory това се използва за изграждане на нашите заявки
  • HttpTransport абстракция на транспортния слой на ниско ниво HTTP
  • GenericUrl клас, който обгръща URL адреса
  • HttpRequest обработва действителното изпълнение на заявката

Ще разгледаме всичко това и един по-сложен пример с действителен API, който връща JSON формат в следващите раздели.

4. Сменяем HTTP транспорт

Библиотеката има добре абстрахиран клас HttpTransport, който ни позволява да изградим върху него и да преминем към основната избрана HTTP транспортна библиотека на ниско ниво :

public class GitHubExample { static HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); }

В този пример използваме NetHttpTransport , който се основава на HttpURLConnection, който се намира във всички Java SDK. Това е добър начален избор, тъй като е добре познат и надежден.

Разбира се, може да има случай, в който се нуждаем от разширено персонализиране, а оттам и изискването за по-сложна библиотека от ниско ниво.

За този вид случаи има ApacheHttpTransport:

public class GitHubExample { static HttpTransport HTTP_TRANSPORT = new ApacheHttpTransport(); }

В ApacheHttpTransport е базиран на популярния Apache HttpClient която включва голямо разнообразие от възможности за избор, за да изберете връзки.

Освен това библиотеката предоставя възможност за изграждане на вашето изпълнение на ниско ниво, което го прави много гъвкав.

5. JSON разбор

Клиентът на Google Http включва друга абстракция за синтактичен анализ на JSON. Основно предимство на това е, че изборът на библиотека за анализ на ниско ниво е взаимозаменяем .

Има три вградени възможности за избор, всички които разширяват JsonFactory и включва също възможността да внедрим собствения си.

5.1. Сменяема библиотека за разбор

В нашия пример ще използваме внедряването на Jackson2, което изисква зависимостта google-http-client-jackson2 :

 com.google.http-client google-http-client-jackson2 1.23.0 

След това вече можем да включим JsonFactory:

public class GitHubExample { static HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); staticJsonFactory JSON_FACTORY = new JacksonFactory(); }

В JacksonFactory е най-бързият и най-популярната библиотека за операции разбор / сериализация.

Това се дължи на размера на библиотеката (което може да бъде проблем в определени ситуации). Поради тази причина Google предоставя и GsonFactory , която е реализация на библиотеката на Google GSON, лека библиотека за синтактичен анализ на JSON.

Съществува и възможността да напишем нашата реализация на анализатор на ниско ниво.

5.2. Анотация на @ Key

Можем да използваме анотацията @Key, за да посочим полета, които трябва да бъдат анализирани или сериализирани в JSON:

public class User { @Key private String login; @Key private long id; @Key("email") private String email; // standard getters and setters }

Тук правим абстракция на потребител , която получаваме пакетно от GitHub API (ще стигнем до реалния анализ по-късно в тази статия) .

Моля, обърнете внимание, че полетата, които нямат анотацията @Key, се считат за вътрешни и не се анализират или сериализират в JSON . Освен това видимостта на полетата няма значение, както и съществуването на методите getter или setter.

Можем да посочим стойността на @Key анотацията, за да я присвоим на правилния JSON ключ.

5.3. GenericJson

Анализират се само полетата, които декларираме и маркираме като @Key .

За да запазим другото съдържание, можем да декларираме нашия клас за разширяване на GenericJson:

public class User extends GenericJson { //... }

GenericJson реализира интерфейса Map , което означава, че можем да използваме методите get и put, за да зададем / получим JSON съдържание в заявката / отговора.

6. Осъществяване на повикване

За да се свържем с крайна точка с Google Http Client, ще ни трябва HttpRequestFactory , която ще бъде конфигурирана с предишните ни абстракции HttpTransport и JsonFactory:

public class GitHubExample { static HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); static JsonFactory JSON_FACTORY = new JacksonFactory(); private static void run() throws Exception { HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory( (HttpRequest request) -> { request.setParser(new JsonObjectParser(JSON_FACTORY)); }); } }

Следващото нещо, от което ще се нуждаем, е URL адрес, към който да се свържем. Библиотеката обработва това като клас, разширяващ GenericUrl, в който всяко декларирано поле се третира като параметър на заявката:

public class GitHubUrl extends GenericUrl { public GitHubUrl(String encodedUrl) { super(encodedUrl); } @Key public int per_page; }

Тук, в нашия GitHubUrl, декларираме свойството per_page, за да посочим колко потребители искаме в едно извикване на API на GitHub.

Нека продължим да изграждаме нашето обаждане с помощта на GitHubUrl:

private static void run() throws Exception { HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory( (HttpRequest request) -> { request.setParser(new JsonObjectParser(JSON_FACTORY)); }); GitHubUrl url = new GitHubUrl("//api.github.com/users"); url.per_page = 10; HttpRequest request = requestFactory.buildGetRequest(url); Type type = new TypeToken
    
     () {}.getType(); List users = (List)request .execute() .parseAs(type); }
    

Notice how we specify how many users we'll need for the API call, and then we build the request with the HttpRequestFactory.

Following this, since the GitHub API's response contains a list of users, we need to provide a complex Type, which is a List.

Then, on the last line, we make the call and parse the response to a list of our User class.

7. Custom Headers

One thing we usually do when making an API request is to include some kind of custom header or even a modified one:

HttpHeaders headers = request.getHeaders(); headers.setUserAgent("Baeldung Client"); headers.set("Time-Zone", "Europe/Amsterdam");

We do this by getting the HttpHeaders after we've created our request but before executing it and adding the necessary values.

Please be aware that the Google Http Client includes some headers as special methods. The User-Agent header for example, if we try to include it with just the set method it would throw an error.

8. Exponential Backoff

Another important feature of the Google Http Client is the possibility to retry requests based on certain status codes and thresholds.

We can include our exponential backoff settings right after we've created our request object:

ExponentialBackOff backoff = new ExponentialBackOff.Builder() .setInitialIntervalMillis(500) .setMaxElapsedTimeMillis(900000) .setMaxIntervalMillis(6000) .setMultiplier(1.5) .setRandomizationFactor(0.5) .build(); request.setUnsuccessfulResponseHandler( new HttpBackOffUnsuccessfulResponseHandler(backoff));

Exponential Backoff is turned off by default in HttpRequest, so we must include an instance of HttpUnsuccessfulResponseHandler to the HttpRequest to activate it.

9. Logging

The Google Http Client uses java.util.logging.Logger for logging HTTP request and response details, including URL, headers, and content.

Commonly, logging is managed using a logging.properties file:

handlers = java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = ALL com.google.api.client.http.level = ALL

In our example we use ConsoleHandler, but it's also possible to choose the FileHandler.

The properties file configures the operation of the JDK logging facility. This config file can be specified as a system property:

-Djava.util.logging.config.file=logging.properties

So after setting the file and system property, the library will produce a log like the following:

-------------- REQUEST -------------- GET //api.github.com/users?page=1&per_page=10 Accept-Encoding: gzip User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip) Nov 12, 2017 6:43:15 PM com.google.api.client.http.HttpRequest execute curl -v --compressed -H 'Accept-Encoding: gzip' -H 'User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip)' -- '//api.github.com/users?page=1&per_page=10' Nov 12, 2017 6:43:16 PM com.google.api.client.http.HttpResponse -------------- RESPONSE -------------- HTTP/1.1 200 OK Status: 200 OK Transfer-Encoding: chunked Server: GitHub.com Access-Control-Allow-Origin: * ... Link: ; rel="next", ; rel="first" X-GitHub-Request-Id: 8D6A:1B54F:3377D97:3E37B36:5A08DC93 Content-Type: application/json; charset=utf-8 ...

10. Conclusion

In this tutorial, we've shown the Google HTTP Client Library for Java and its more useful features. Their Github contains more information about it as well as the source code of the library.

Както винаги, пълният изходен код на този урок е достъпен в GitHub.