📜 ⬆️ ⬇️

Features HttpUrlConnection from java.net

Hello,

Today I will try to talk about how you can send a request and read the response from the HTTP server using URLConnection from the JRE library.

We are currently learning Java online. Our entire team uses Slack for work and communication. For information on users, we use Slack API. In order not to talk about the API itself for a long time (this is a topic for a separate article), I’ll say briefly: Slack API is built on the HTTP protocol . slack.com Here is a list of some methods:

To get the user list, users need the users.list method. We form the URI - /api/users.list in the request body there should be an authentication token in the form application / x-www-form-urlencoded, that is, the request should look something like this (but there is one nuance which will be lower):
')
GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5 


I knew about the Apache HttpComponents library, but for research purposes we will use the tools available in the standard Java 8 library, namely the implementation of java.net.URLConnection.

To get the URLConnection entity, you need to use an object of the java.net.URL class, its constructor takes the type String where, in addition to everything, the protocol must be specified - in our case https.

After getting the entity URL, call the openConnection () method which will return the HttpsUrlConnection entity.

 String url = “https://slack.com/api/users.list”; URLConnection connection = new URL(url).openConnection(); 

At the same time, you need to handle or forward MalformedUrlException and IOException.

After this, the connection variable will store the reference to the HttpsUrlConnectionImpl object. By default, a GET request will be formed in order to add a Header using the setRequestProperty () method, which accepts key and value. We need to set here a Content-Type that has the value application / x-www-form-urlencoded . Well, and we do it!
 connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded”); 

Now it remains only to send a request by writing our token and limit to the body. To do this, set the doOutput field of the connection object to true, using the setDoOutput () method;

 connection.setDoOutput(true); 

Next, the most interesting part is to somehow transfer our request body to the OutputStream. We will use OutputStreamWriter:

 OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); 

There is one caveat: after we called the getOutputStream () method, the request method changes to POST, since GET does not provide for the request body, but the benefit is that slack does not impose a hard limit on the method, so everything was fine. And so the GET request should look like this:
 GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded 

But I did not begin to alter. And instead our request turned out like this:

 POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5 

(* some headers are put by the HttpsUrlConnection themselves and are missing here)

And so to write our request body we use write () ;.
 String reqBody = “token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100”; writer.write(reqBody); writer.close(); 

After that, our request will be sent, and we can read the response received. It is important to close the OutputStream or flush () before receiving the InputStream, otherwise the data will not leave the buffer (alternatively, you can use PrintStream - in the println () method, flush () is called by default). For reading used BufferedReader:
 StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + “\r\n”); reader.close(); 

(* use lines () to get a Stream on output; \ r \ n - the character CRLF - inserts a newline)

And, if we successfully pass authentication, the respBody variable should store our response from the server, which in our case is a JSON object. After that, it can be sent to the next stage of processing.

After some optimization, everything looks like this:

 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()))); } } } 

Hope it was helpful!

Source: https://habr.com/ru/post/459080/


All Articles