Um guia para o Google-Http-Client
1. Visão geral
Neste artigo, daremos uma olhada emGoogle HTTP Client Library for Java, que é uma biblioteca rápida e bem abstrata para acessar qualquer recurso por meio do protocolo de conexão HTTP.
Os principais recursos do cliente são:
-
uma camada de abstração HTTP que permite dissociar qualquer biblioteca de baixo nível
-
modelos de análise JSON e XML rápidos, eficientes e flexíveis da resposta HTTP e solicitar conteúdo
-
anotações e abstrações fáceis de usar para mapeamentos de recursos HTTP
A biblioteca também pode ser usada no Java 5 e superior, tornando-a uma opção considerável para projetos legados (SE e EE).
Neste artigo, vamos desenvolver um aplicativo simples quewill connect to the GitHub API and retrieve users, ao mesmo tempo que aborda alguns dos recursos mais interessantes da biblioteca.
2. Dependências do Maven
Para usar a biblioteca, precisaremos da dependênciagoogle-http-client:
com.google.http-client
google-http-client
1.23.0
A versão mais recente pode ser encontrada emMaven Central.
3. Fazendo uma solicitação simples
Vamos começar fazendo uma simples solicitação GET para a página GitHub para mostrar como o Google Http Client funciona fora da caixa:
HttpRequestFactory requestFactory
= new NetHttpTransport().createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(
new GenericUrl("https://github.com"));
String rawResponse = request.execute().parseAsString()
Para tornar a solicitação mais simples, precisaremos de pelo menos:
-
HttpRequestFactory isso é usado para construir nossas solicitações
-
HttpTransport uma abstração da camada de transporte HTTP de baixo nível
-
GenericUrl uma classe que envolve o Url
-
HttpRequest lida com a execução real da solicitação
Veremos tudo isso e um exemplo mais complexo com uma API real que retorna um formato JSON nas seções a seguir.
4. Transporte HTTP plugável
A biblioteca tem uma classeHttpTransport bem abstraída que nos permite construir sobre ela echange to the underlying low-level HTTP transport library of choice:
public class GitHubExample {
static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
}
Neste exemplo, estamos usandoNetHttpTransport, que se baseia emHttpURLConnection que é encontrado em todos os SDKs Java. Esta é uma boa escolha de partida, pois é bem conhecida e confiável.
Obviamente, pode haver o caso em que precisamos de alguma personalização avançada e, portanto, a exigência de uma biblioteca de baixo nível mais complexa.
Para este tipo de caso, existe oApacheHttpTransport:
public class GitHubExample {
static HttpTransport HTTP_TRANSPORT = new ApacheHttpTransport();
}
OApacheHttpTransport é baseado no popularApache HttpClient, que inclui uma ampla variedade de opções para configurar conexões.
Além disso, a biblioteca oferece a opção de criar sua implementação de baixo nível, tornando-a muito flexível.
5. Análise JSON
O Google Http Client inclui outra abstração para análise JSON. Uma grande vantagem disso é quethe choice of low-level parsing library is interchangeable.
Existem três opções integradas, todas estendendoJsonFactory, e também inclui a possibilidade de implementar a nossa.
5.1. Biblioteca intercambiável de análise
Em nosso exemplo, vamos usar a implementação Jackson2, que requer a dependênciagoogle-http-client-jackson2:
com.google.http-client
google-http-client-jackson2
1.23.0
Depois disso, podemos agora incluir oJsonFactory:
public class GitHubExample {
static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
staticJsonFactory JSON_FACTORY = new JacksonFactory();
}
OJacksonFactory é a biblioteca mais rápida e popular para operações de análise / serialização.
Isso tem o custo do tamanho da biblioteca (o que pode ser uma preocupação em determinadas situações). Por esse motivo, o Google também fornece oGsonFactory, que é uma implementação da biblioteca GSON do Google, uma biblioteca de análise JSON leve.
Também há a possibilidade de escrever nossa implementação de analisador de baixo nível.
5.2. A anotação de @Key
Podemos usar a anotação@Key para indicar campos que precisam ser analisados ou serializados para JSON:
public class User {
@Key
private String login;
@Key
private long id;
@Key("email")
private String email;
// standard getters and setters
}
Aqui, estamos fazendo uma abstraçãoUser, que recebemos em lote da API do GitHub (veremos a análise real posteriormente neste artigo).
Observe quefields that don’t have the @Key annotation are considered internal and are not parsed from or serialized to JSON. Além disso, a visibilidade dos campos não importa, nem a existência dos métodos getter ou setter.
Podemos especificar o valor da anotação@Key, para mapeá-la para a chave JSON correta.
5.3. GenericJson
Apenas os campos que declaramos e marcamos como@Key são analisados.
Para reter o outro conteúdo, podemos declarar nossa classe para estenderGenericJson:
public class User extends GenericJson {
//...
}
GenericJson implementa a interfaceMap, o que significa que podemos usar os métodos get e put para definir / obter conteúdo JSON na solicitação / resposta.
6. Fazendo a ligação
Para se conectar a um endpoint com o Google Http Client, precisaremos de umHttpRequestFactory, que será configurado com nossas abstrações anterioresHttpTransporteJsonFactory:
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));
});
}
}
A próxima coisa de que precisaremos é um URL para conectar. A biblioteca trata isso como uma classe que estendeGenericUrl em que qualquer campo declarado é tratado como um parâmetro de consulta:
public class GitHubUrl extends GenericUrl {
public GitHubUrl(String encodedUrl) {
super(encodedUrl);
}
@Key
public int per_page;
}
Aqui em nossoGitHubUrl,, declaramos a propriedadeper_page para indicar quantos usuários queremos em uma única chamada para a API do GitHub.
Vamos continuar construindo nossa chamada usando oGitHubUrl:
private static void run() throws Exception {
HttpRequestFactory requestFactory
= HTTP_TRANSPORT.createRequestFactory(
(HttpRequest request) -> {
request.setParser(new JsonObjectParser(JSON_FACTORY));
});
GitHubUrl url = new GitHubUrl("https://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);
}
Observe como especificamos quantos usuários precisaremos para a chamada de API e, em seguida, construímos a solicitação comHttpRequestFactory.
Em seguida, como a resposta da API do GitHub contém uma lista de usuários, precisamos fornecer umType complexo, que é umList<User>.
Então, na última linha, fazemos a chamada e analisamos a resposta a uma lista de nossa classeUser.
7. Cabeçalhos personalizados
Uma coisa que costumamos fazer ao fazer uma solicitação de API é incluir algum tipo de cabeçalho personalizado ou mesmo um modificado:
HttpHeaders headers = request.getHeaders();
headers.setUserAgent("example Client");
headers.set("Time-Zone", "Europe/Amsterdam");
Fazemos isso obtendoHttpHeaders depois de criarmos nossa solicitação, mas antes de executá-la e adicionar os valores necessários.
Esteja ciente de que o cabeçalho do cliente HTTPincludes some headers as special methods. do GoogleUser-Agent por exemplo, se tentarmos incluí-lo apenas com o método set, ocorrerá um erro.
8. Retorno Exponencial
Outro recurso importante do Google Http Client é a possibilidade de repetir solicitações com base em determinados códigos e limites de status.
Podemos incluir nossas configurações de backoff exponencial logo depois de criarmos nosso objeto de solicitação:
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, então devemos incluir uma instância deHttpUnsuccessfulResponseHandler paraHttpRequest para ativá-lo.
9. Exploração madeireira
O Google Http Client usajava.util.logging.Logger para registrar detalhes de solicitação e resposta HTTP, incluindo URL, cabeçalhos e conteúdo.
Normalmente, o registro é gerenciado usando um arquivologging.properties:
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL
com.google.api.client.http.level = ALL
Em nosso exemplo, usamosConsoleHandler, mas também é possível escolher oFileHandler.
O arquivo de propriedades configura a operação do recurso de log do JDK. Este arquivo de configuração pode ser especificado como uma propriedade do sistema:
-Djava.util.logging.config.file=logging.properties
Portanto, após definir a propriedade do arquivo e do sistema, a biblioteca produzirá um log como o seguinte:
-------------- REQUEST --------------
GET https://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)' -- 'https://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. Conclusão
Neste tutorial, mostramos a biblioteca cliente HTTP do Google para Java e seus recursos mais úteis. SeuGithub contém mais informações sobre ele, bem como o código-fonte da biblioteca.
Como sempre, o código-fonte completo deste tutorial está disponívelover on GitHub.