Olá
Hoje vou tentar falar sobre como você pode enviar uma solicitação e ler a resposta do servidor HTTP usando o URLConnection da biblioteca JRE.
No momento, estamos aprendendo Java online. Toda a nossa equipe usa o Slack para trabalho e comunicação. Para obter informações sobre usuários, usamos a API do Slack. Para não falar sobre a própria API por um longo tempo (este é um tópico para um artigo separado), direi brevemente: a Slack API é construída sobre o protocolo HTTP, para obter informações sobre os usuários, você precisa enviar uma solicitação com um URI no qual deve haver um nome de método da API para a API do endereço do host
. slack.com Aqui está uma lista de alguns métodos:
- users.list
- chat.postMessage
- conversations.create
- files.upload
- im.open
Para obter uma lista de usuários, você precisa do método users.list. Como formamos o URI -
/api/users.list no corpo da solicitação, deve haver um token de autenticação no formulário application / x-www-form-urlencoded, ou seja, a solicitação deve se parecer com isso (mas há uma nuance menor):
GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
Eu conhecia a biblioteca Apache HttpComponents, mas para fins de pesquisa, usaremos as ferramentas disponíveis na biblioteca Java 8 padrão, a saber, a implementação de java.net.URLConnection.
Para obter a entidade URLConnection, você precisa usar um objeto da classe java.net.URL, seu construtor usa o tipo String onde, além de tudo, o protocolo deve ser especificado - no nosso caso, https.
Depois de receber a entidade URL, chamamos o método
openConnection () que retornará a entidade HttpsUrlConnection.
String url = “https:
Nesse caso, você precisa manipular ou lançar MalformedUrlException e IOException.
Depois disso, a variável de conexão armazenará uma referência ao objeto HttpsUrlConnectionImpl. Por padrão, uma solicitação GET será gerada. Para adicionar um cabeçalho, usamos o método
setRequestProperty () , que aceita chave e valor. Precisamos instalar um tipo de conteúdo aqui que tenha o valor
application / x-www-form-urlencoded . Bem, e nós fazemos!
connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded”);
Agora resta apenas enviar uma solicitação escrevendo nosso token e limite no corpo. Para fazer isso, defina o campo doOutput do objeto de conexão como true usando o método
setDoOutput () ;
connection.setDoOutput(true);
A seguir, a parte mais interessante - você precisa, de alguma forma, passar nosso corpo de solicitação para um OutputStream. Usaremos OutputStreamWriter:
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
Há uma ressalva: depois que chamamos o método getOutputStream (), o método request muda para POST, pois GET não fornece o corpo da solicitação, mas como o slack não impõe uma restrição estrita ao método, tudo correu bem. E assim a solicitação GET deve ficar assim:
GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded
Mas não comecei a refazê-lo. E, em vez disso, nosso pedido acabou assim:
POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
(* alguns cabeçalhos são definidos pelo próprio HttpsUrlConnection e estão ausentes aqui)
E assim, para escrever nosso corpo de solicitação, usamos write ();.
String reqBody = “token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100”; writer.write(reqBody); writer.close();
Depois disso, nosso pedido será enviado e podemos ler a resposta recebida. É importante fechar OutputStream ou flush () antes de receber um InputStream, caso contrário, os dados não sairão do buffer (como alternativa, você pode usar PrintStream - no método println (), flush () é chamado por padrão). Para a leitura, usei o BufferedReader:
StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + “\r\n”); reader.close();
(* use lines () para obter fluxo na saída; \ r \ n - caractere CRLF - insere uma transição para uma nova linha)
E, se autenticarmos com êxito, a variável respBody deverá armazenar nossa resposta do servidor, que no nosso caso é um objeto JSON. Depois disso, ele pode ser enviado para a próxima etapa do processamento.
Após alguma otimização, tudo fica assim:
package main.java.com.bilichenko.learning; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.Optional; import java.util.stream.Collectors; public class SlackClient { private static final String HOST = "https://api.slack.com"; private static final String GET_USERS_URI = "/api/users.list"; private static final String TOKEN = "xx-ooo-YOUR-TOKEN-HERE"; public static void main(String[] args) throws IOException { SlackClient slackClient = new SlackClient(); System.out.println(slackClient.getRawResponse(HOST + GET_USERS_URI, "application/x-www-form-urlencoded", "token=" + TOKEN).orElse("no response")); } public Optional<String> getRawResponse(String url, String contentType, String requestBody) throws MalformedURLException, IOException { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("Content-Type", contentType); connection.setConnectTimeout(10000); connection.setRequestMethod("POST"); connection.setDoOutput(true); try(OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { writer.write(requestBody); } if (connection.getResponseCode() != 200) { System.err.println("connection failed"); return Optional.empty(); } try(BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream(), Charset.forName("utf-8")))) { return Optional.of(reader.lines().collect(Collectors.joining(System.lineSeparator()))); } } }
Espero que tenha sido útil!