Bonjour
Aujourd'hui, je vais essayer de vous expliquer comment envoyer une demande et lire la réponse du serveur HTTP à l'aide de URLConnection de la bibliothÚque JRE.
Nous apprenons actuellement Java en ligne. Toute notre Ă©quipe utilise Slack pour le travail et la communication. Pour plus d'informations sur les utilisateurs, nous utilisons l'API Slack. Afin de ne pas parler de l'API elle-mĂȘme pendant longtemps (c'est un sujet pour un article sĂ©parĂ©), je dirai briĂšvement: l'API Slack est construite sur le protocole HTTP, pour obtenir des informations sur les utilisateurs, vous devez envoyer une demande avec un URI dans lequel il doit y avoir un nom de mĂ©thode de l'API vers l'
api de l' adresse hĂŽte
. slack.com Voici une liste de quelques méthodes:
- users.list
- chat.postMessage
- conversations.créer
- files.upload
- im.open
Pour obtenir une liste d'utilisateurs, vous avez besoin de la méthode users.list. Nous formons l'URI -
/api/users.list dans le corps de la demande, il devrait y avoir un jeton d'authentification sous la forme application / x-www-form-urlencoded, c'est-à -dire que la demande devrait ressembler à ceci (mais il y a une nuance qui sera inférieure):
GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
Je connaissais la bibliothÚque Apache HttpComponents, mais à des fins de recherche, nous utiliserons les outils disponibles dans la bibliothÚque Java 8 standard, à savoir l'implémentation de java.net.URLConnection.
Pour obtenir l'entitĂ© URLConnection, vous devez utiliser l'objet de la classe java.net.URL, son constructeur prend le type String oĂč, en plus de tout, le protocole doit ĂȘtre spĂ©cifiĂ© - dans notre cas, https.
AprÚs avoir reçu l'entité URL, nous appelons la méthode
openConnection () qui renverra l'entité HttpsUrlConnection.
String url = âhttps:
Dans ce cas, vous devez gérer ou lever MalformedUrlException et IOException.
AprĂšs cela, la variable de connexion stockera une rĂ©fĂ©rence Ă l'objet HttpsUrlConnectionImpl. Par dĂ©faut, une requĂȘte GET sera gĂ©nĂ©rĂ©e. Pour ajouter un en-tĂȘte, nous utilisons la mĂ©thode
setRequestProperty () , qui accepte la clé et la valeur. Nous devons installer ici un Content-Type qui a la valeur
application / x-www-form-urlencoded . Eh bien, et nous le faisons!
connection.setRequestProperty(âContent-Typeâ, âapplication/x-www-form-urlencodedâ);
Maintenant, il ne reste plus qu'à envoyer une demande en écrivant notre jeton et à limiter dans le corps. Pour ce faire, définissez le champ doOutput de l'objet de connexion sur true à l'aide de la méthode
setDoOutput () ;
connection.setDoOutput(true);
Ensuite, la partie la plus intéressante - vous devez en quelque sorte passer notre corps de demande à un OutputStream. Nous utiliserons OutputStreamWriter:
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
Il y a une mise en garde: aprÚs avoir appelé la méthode getOutputStream (), la méthode de demande passe à POST, car GET ne fournit pas le corps de la demande, mais comme slack n'impose pas de restriction stricte à la méthode, tout allait bien. Et donc la demande GET devrait ressembler à ceci:
GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded
Mais je n'ai pas recommencé. Et à la place, notre demande s'est avérée comme ceci:
POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5
(* certains en-tĂȘtes sont dĂ©finis par HttpsUrlConnection eux-mĂȘmes et ils sont absents ici)
Et donc, pour Ă©crire notre corps de requĂȘte, nous utilisons write ();.
String reqBody = âtoken=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100â; writer.write(reqBody); writer.close();
AprÚs cela, notre demande sera envoyée et nous pourrons lire la réponse reçue. Il est important de fermer OutputStream ou de faire flush () avant de recevoir un InputStream, sinon les données ne quitteront pas le tampon (vous pouvez également utiliser PrintStream - dans la méthode println (), flush () est appelé par défaut). Pour la lecture, j'ai utilisé BufferedReader:
StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + â\r\nâ); reader.close();
(* utilisez les lignes () pour obtenir Stream sur la sortie; \ r \ n - caractĂšre CRLF - insĂšre une transition vers une nouvelle ligne)
Et, si nous nous authentifions avec succĂšs, la variable respBody devrait stocker notre rĂ©ponse du serveur, qui dans notre cas est un objet JSON. AprĂšs cela, il peut ĂȘtre envoyĂ© Ă la prochaine Ă©tape du traitement.
AprĂšs quelques optimisations, tout ressemble Ă ceci:
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()))); } } }
J'espÚre que cela a été utile!