{"id":255,"date":"2020-01-02T11:45:29","date_gmt":"2020-01-02T06:15:29","guid":{"rendered":"https:\/\/openapex.org\/spaces\/software\/?p=255"},"modified":"2022-03-02T01:03:57","modified_gmt":"2022-03-01T19:33:57","slug":"a-full-fledged-http-client","status":"publish","type":"post","link":"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html","title":{"rendered":"A Full-Fledged Java-Based HTTP Client"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mutesoft.com\/spaces\/software\/wp-content\/uploads\/sites\/7\/2022\/02\/image-1024x561.png\" alt=\"Plain Java-Based HTTP Client\" class=\"wp-image-971\" width=\"768\" height=\"421\" srcset=\"https:\/\/mutesoft.com\/spaces\/software\/wp-content\/uploads\/sites\/7\/2022\/02\/image-1024x561.png 1024w, https:\/\/mutesoft.com\/spaces\/software\/wp-content\/uploads\/sites\/7\/2022\/02\/image-300x164.png 300w, https:\/\/mutesoft.com\/spaces\/software\/wp-content\/uploads\/sites\/7\/2022\/02\/image-768x421.png 768w, https:\/\/mutesoft.com\/spaces\/software\/wp-content\/uploads\/sites\/7\/2022\/02\/image.png 1354w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><figcaption>Plain Java-Based HTTP Client<\/figcaption><\/figure><\/div>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#1_Context\" >1. Context<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#2_Approach\" >2. Approach<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#3_Send_Request_and_Receive_Response\" >3. Send Request and Receive Response<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#4_Read_Response\" >4. Read Response<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#5_Run_the_Program\" >5. Run the Program<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/mutesoft.com\/spaces\/software\/a-full-fledged-http-client.html\/#6_Conclusion\" >6. Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\" id=\"1-context\"><span class=\"ez-toc-section\" id=\"1_Context\"><\/span><strong>1. Context<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>We are going to write a mini-browser that can establish a connection with any website (<code>URL<\/code>) over <code>HTTP<\/code> protocol and then send requests &amp; receive response messages. For example, you may hit <code>https:\/\/google.com<\/code> and receive the <code>HTML<\/code> content or hit a REST API endpoint and receive JSON content. We use plain Java and do not use any third-party library. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2-approach\"><span class=\"ez-toc-section\" id=\"2_Approach\"><\/span><strong>2. Approach<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><code>java.net package<\/code> provides interfaces and classes to establish a communication link between client and server over the network. Following steps are involved when <code>java.net.HttpURLConnection<\/code> is used for communication over <code>HTTP<\/code>:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Create a <code>URL<\/code> object<\/li><li>Call <code>openConnection()<\/code> on <code>URL<\/code> to get a connection<\/li><li>Add necessary connection properties and request headers<\/li><li>Establish the actual connection by calling <code>connect()<\/code> method on <code>HttpURLConnection<\/code><\/li><li>Read response headers from the connection<\/li><li>Read the response as input stream obtained from the connection<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3-send-request-and-receive-response\"><span class=\"ez-toc-section\" id=\"3_Send_Request_and_Receive_Response\"><\/span><strong>3. Send Request and Receive Response<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The <code>sendRequest()<\/code> method sequentially calls methods to create <code>URL<\/code>, get Http URL connection, set up connection properties, add request headers, establish an actual connection, and finally receive HTTP response.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Opens a connection and sends Http request to given URL.\n * @param url URL to be invoked.\n * @return Response as a stream.\n *\/\nprivate InputStream sendRequest(String url) {\n    try {\n        URL urlInstance = new URL(url);\n        HttpURLConnection connection = (HttpURLConnection) urlInstance.\n                openConnection();\n        \/\/ Set timeout in milliseconds\n        connection.setConnectTimeout(20000);\n        \/\/ Set request headers\n        addRequestHeaders(connection);\n        \/\/ Establiish a connection\n        connection.connect();\n        \/\/ Read response status and headers\n        readResponseStatusAndHeaders(connection);\n        \/\/ Return response\n        return connection.getInputStream();\n    } catch (IOException ex) {\n        ex.printStackTrace();\n    }\n    return null;\n}<\/pre>\n\n\n\n<p>The following method adds HTTP request headers to the connection. Get the complete list of request headers from&nbsp;<a href=\"http:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_headers\">here.<\/a><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Adds request headers to connection.\n * @param connection Http URL connection instance.\n *\/\nprivate void addRequestHeaders(HttpURLConnection connection) {\n    connection.addRequestProperty(\"Accept\", \"text\/plain\");\n    connection.addRequestProperty(\"Accept-Language\", \"en\");\n    connection.addRequestProperty(\"Cache-Control\", \"no-cache\");\n}<\/pre>\n\n\n\n<p>The following method extracts the response code, response message, and response headers from the connection. Get the complete list of response headers from&nbsp;<a href=\"http:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_headers\">here.<\/a><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Reads response code, message and header fields.\n * @param connection Http URL connection instance.\n * @throws IOException If an error occrred while connecting to server.\n *\/\nprivate void readResponseStatusAndHeaders(HttpURLConnection connection) throws\n        IOException {\n    System.out.println(\"Response code: \" + connection.getResponseCode());\n    System.out.println(\n            \"Response message: \" + connection.getResponseMessage());\n    System.out.println(\"Response header: Content-Length: \" + connection.\n            getHeaderField(\"Content-Length\"));\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4-read-response\"><span class=\"ez-toc-section\" id=\"4_Read_Response\"><\/span><strong>4. Read Response<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Finally, extract the response data from the input stream obtained from the connection.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Prints the response to console.\n * @param response Response stream.\n *\/\nprivate void processResponse(InputStream response) {\n    if (response == null) {\n        System.out.println(\"No or blank response received\");\n    } else {\n        StringBuilder data = new StringBuilder();\n        try {\n            int bufferSize = 2048;\n            byte[] inputData = new byte[bufferSize];\n            int count = 0;\n            while ((count = response.read(inputData, 0, bufferSize)) != -1) {\n                data.append(new String(inputData, 0, count, \"UTF-8\"));\n            }\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n        System.out.println(\"Data received: \" + data.toString());\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5-run-the-program\"><span class=\"ez-toc-section\" id=\"5_Run_the_Program\"><\/span><strong>5. Run the Program<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Here is the <code>main<\/code> method to test the <code>HttpClient<\/code>. It accepts the <code>URL<\/code> as string input from the user. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Main method of the program.\n * @param args Input arguments to the program.\n *\/\npublic static void main(String[] args) {\n    HttpClient handler = new HttpClient(false);\n    Scanner scanner = new Scanner(System.in);\n    while(true) {\n        System.out.println(\"URL (q to quit):\");\n        String url = scanner.nextLine();\n        if(!url.equalsIgnoreCase(\"q\")) {\n            InputStream response = handler.sendRequest(url.trim());\n            handler.processResponse(response);\n        } else {\n            break;\n        }\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6-conclusion\"><span class=\"ez-toc-section\" id=\"6_Conclusion\"><\/span><strong>6. Conclusion<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You may download the complete source code from here: <a rel=\"noreferrer noopener\" aria-label=\"HttpClient.java (opens in a new tab)\" href=\"https:\/\/github.com\/fiveobjects\/reference\/blob\/master\/java\/misc\/src\/main\/java\/org\/openapex\/samples\/misc\/http\/HttpClient.java\" target=\"_blank\">HttpClient.java<\/a>. For a sophisticated and efficient <code>HttpClient<\/code> use <a rel=\"noreferrer noopener\" aria-label=\"Apache HttpClient (opens in a new tab)\" href=\"https:\/\/hc.apache.org\/httpcomponents-client-5.0.x\/index.html\" target=\"_blank\">Apache HttpClient<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are going to write a mini-browser that can establish a connection with any website (URL) over HTTP protocol and then send requests &#038; receive response messages. For example, you may hit https:\/\/google.com and receive the HTML content or hit a REST API endpoint and receive JSON content.<\/p>\n","protected":false},"author":2,"featured_media":971,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"","_seopress_titles_desc":"We are going to write a mini-browser that can establish a connection with any website (URL) over HTTP protocol and then send requests &amp; receive response messages. For example, you may hit https:\/\/google.com and receive the HTML content or hit a  REST API endpoint and receive JSON content. We use plain Java and do not use any third-party library. ","_seopress_robots_index":"","_vp_format_video_url":"","_vp_image_focal_point":{"x":0.5,"y":0.5},"footnotes":""},"categories":[6],"tags":[34,9],"class_list":["post-255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","tag-http","tag-java"],"_links":{"self":[{"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/posts\/255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/comments?post=255"}],"version-history":[{"count":13,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/posts\/255\/revisions"}],"predecessor-version":[{"id":1013,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/posts\/255\/revisions\/1013"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/media\/971"}],"wp:attachment":[{"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/media?parent=255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/categories?post=255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mutesoft.com\/spaces\/software\/wp-json\/wp\/v2\/tags?post=255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}