What is the world?
There are different types of software you'll need to write, from small utilities to enterprise software. Despite the size, they will rarely be stand-alone applications functioning within their own environment. More likely they will be working with local storage (a local hard drive), communicating with other applications locally, or reaching out to remote services over the network.
In this chapter, we will cover three kinds of interactions:
Getting input from the user
Fetching data on the internet
Writing to a file
For this, we will ask for a URL, make sure it is correct, fetch the content addressed by the URL, and write it to a file.
Get and validate input from the user
User input can be gathered either when the program is started, using command-line arguments, or by prompting the user at any point during the program execution.
Checking for a command-line input
The following code is located inside a UserInput
class, itself part of a communication
package.
When user-defined elements are provided at program startup, they are made available in the args
array of the main function. Here is the code for the class with a main function that:
Checks whether an argument has been provided
Prompts the user for a URL if not
Displays whether the URL is formatted correctly or not
package communication;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
/** Demo of getting and checking User input
*
* @author The OpenClassrooms Education Team
*
*/
public class UserInput {
/** Check if user has provided a URL from the command line
* If not prompt for one
* In both cases make sure the URL is well-formed!
* @param args either nothing or a URL string
*/
public static void main(String[] args) {
String urlString="";
// assign a value to urlString or exit
switch(args.length) {
case 0:
urlString=askForUrl();
break;
case 1:
urlString=args[0];
break;
default:
System.out.println("Please run the program with the desired URL or no argument at all");
System.exit(-1);
}
System.out.println("Checking URL " + urlString);
if (isValidURL(urlString)) {
System.out.println(urlString + " is a well-formed URL");
}else {
System.out.println(urlString + " is not a well-formed URL");
}
}
The import
statements exist for the functions that we will define later in this section. Let's move to the main
function. Since we are making a decision based on the different possible values of an expression (the args.length
property) we make use of a switch
statement:
If the user has not provided any argument on the command line, this length is 0. Therefore, call the
askForUrl()
function and assign its result to the urlString variable.If the user has provided one argument, assume it is the URL she wants to provide. Therefore, directly assign this value to the
urlString
variable.If the user has provided more than one argument, you don't know what to do! Therefore, exit with the
System.exit(-1);
statement.
It works! Let's check the implementation of the askforUrl
function.
Asking for an input
/** Prompt user for URL
*
* @return a string representation of the URL entered by the user
*/
public static String askForUrl() {
Scanner readInput=new Scanner(System.in);
System.out.println("Please enter a valid URL");
String url=readInput.nextLine();
readInput.close();
return url;
}
This program makes use of the Scanner class located inside the java.util package. The import statement import java.util.Scanner;
at the beginning of the file, before the class definition, ensures that your program can access it.
First, the Scanner readInput=new Scanner(System.in);
creates an object that contains the readLine()
method and assigns it to the readInput
variable.
Then, the String url=readInput.nextLine();
statement pauses the program until the user enters her input and presses the Enter key. Whatever string has been typed on the command line before pressing the key is then assigned to the url
variable.
Finally, the scanner is closed and the result sent to the calling function thanks to the return url;
statement.
Let's complete this section on user input by checking the validity of the input.
Checking the validity of the provided URL
Getting user input is a terrific first step. Now there is one rule that is essential both for practical and security reasons: always validate user input.
Some users will make mistakes. Others will try to find ways around the security of your application. In order to check that the string provided by the user really represents a URL, Java offers a URL class that will throw an exception if the provided string representation is not a properly formatted URL.
In order to use this class, you need two import statements before your class declaration:
import java.net.MalformedURLException;
import java.net.URL;
Here is the code for the isValidUrl
function that uses the URL
class:
/** Check if a string is a well-formed URL
*
* @param urlString
* @return true if the URL is well formed, else false
*/
private static boolean isValidURL(String urlString) {
try{
new URL(urlString);
// we will never get here if the URL is not well-formed
return true;
}catch (IOException e) {
return false;
}
}
The gist of this code is the new URL(urlString);
statement.
If the URL is formatted correctly, the instantiation works and it returns
true
.If the URL is not formatted correctly, the
MalformedURLException
is raised. Catch it directly and return false in thecatch
statement.
Now that we have all the pieces, let's run the code.
Running the program
We'll use the javac command to compile the program and run it with the java command followed by the package-prefixed name of the class and a URL as the following argument:
$ javac communication/UserInput.java $ java communication.UserInput https://www.openclassrooms.com Checking URL https://www.openclassrooms.com https://www.openclassrooms.com is a well-formed URL
Alternatively, here is the result of running the program with no argument:
$ java communication.UserInput Please enter a valid URL $ https://www.google.com Checking URL https://www.google.com https://www.google.com is a well-formed URL
Sweet! Now that we are able to get some input and check that it consists of a well-formed URL, let's grab the content the URL refers to!
Get the content from a URL with networking
Networking consists of managing a request-response combination over a network, typically the internet.
Your code needs to do the following:
Send a request to the server and wait for a response, or handle the no-network situation.
Wait for response and process the response/or no response.
Why would there be no response?
A no response situation can occur due to various reasons:
You sent request to an incorrect URL
The server is not available (temporarily or permanently)
Processing of the request took too long
… etc.
Let's get on with the request-response code. We'll need to:
Connect to the resource identified by the URL.
Fetch the content and put it in a list.
Connecting to a resource
Let's create a RemoteContent
class inside the same communication
package as the UserInput
class. This allows you to reuse functions created in the UserInput
class.
In the main
function of our RemoteContent
class, we'll prompt the user for a URL. Then we'll connect to the resource it links to. Finally, we'll fetch the content of the resource and store it in memory as a list of strings:
package communication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* Demo of a connection to a remote resource
*
* @author the OpenClassrooms Education Team
*
*/
public class RemoteContent {
/**
* Connect to a resource from a URL and print its content type
* @param args not used in this example
*/
public static void main(String[] args){
// define the string representation of the URL to connect to
String urlString=UserInput.askForUrl();
// connect and print the content type of the retrieved resource
try {
URLConnection myURLConnection=connectFromURL(urlString);
System.out.println("Retrieved a resource of type: " + myURLConnection.getContentType() + " from " + myURLConnection.getURL());
System.out.println(getContent(myURLConnection));
}
// manage errors if the connection fails
catch (MalformedURLException e) {
System.err.println("Malformed URL - " + e.getLocalizedMessage());
}
catch(IOException e){
System.err.println("Cannot establish connection - "+ e.toString());
}
}
The first statement of the main function is String urlString=UserInput.askForUrl();
. It calls the askForUrl()
function from our UserInput
class and assigns the user input string into the urlString
variable.
We then enter a try
block. This means an error encountered during the execution of the block of code will be managed by the corresponding catch
statement. Networking errors inside the try
block can happen when we:
Connect to the resource by calling the
connectFromURL
function.Get the content of the resource and put it in a list with the
getContent
function.
We can define catch blocks for two manageable exceptions:
catch (MalformedURLException e)
will deal with ill-formed URLscatch(IOException e)
will manage errors with accessing the resource
In this program, we simply print an informative message in case of an error. More advanced error handling may deal with retrying to connect or prompting the user for another URL.
Let's now see how the connection is handled.
Connecting to a resource identified with an URL
Here is the code for the connectFromURL function:
/** establish a connection to a provided URL
*
* @param urlString the string of the URL to connect to
* @return an active connection
* @throws IOException if the connection cannot be established
*/
public static URLConnection connectFromURL(String urlString) throws IOException {
URL mySite = new URL(urlString);
URLConnection myURLConnection= mySite.openConnection();
myURLConnection.connect();
return myURLConnection;
}
Here is a three-step process:
Create an instance of an URL from the provided string. As you have already seen, a MalformedURLException exception will be triggered if the URL is not properly formatted. Else, the result is assigned to a
mySite
variable.Instantiate a URLConnection object from the
mySite
instance created in step one, using theopenConnection()
method the URL class provides. As you can see in the documentation, this method will either:Return an instance of the URLConnection class
Throw an IOException if the connection cannot be established
Call the
connect()
method from the created instance. Then return themyURLConnection
object to the calling function.
In the main function, we assign the returned instance of the URLConnection
class to a myURLConnection
variable. Let's see how the getContent
function can fetch the content by receiving this instance as an argument.
Fetch the content from the resource
In the getContent
function, we create an empty list, read the content line by line, and return the list once we reach the end of the content.
/** read the resource content line by line and add each line to a list
*
* @param resource the connected resource
* @return a list of lines of content
* @throws IOException
*/
public static List<String> getContent(URLConnection resource) throws IOException {
List<String>lines=new ArrayList<String>();
BufferedReader in = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
lines.add(line);
}
return lines;
}
The getContent
function declaration provides us with the following information:
It needs to be provided with a
URLConnection
instance as argument that will be assigned to theresource
parameter.It returns a list of strings, as the
List<String>
return type indicates.It can throw an
IOException
exception in case a network error happens.
Inside the function definition:
The first statement creates a new, empty instance of a
List<String>
object that is assigned to thelines
variable.Then create an instance of a BufferedReader that is constructed from an InputStreamReader, itself initialized from the getInputStream() method attached to the
resource
variable that refers to theURLConnection
instance. This provides efficient access to the resource content.The
String line;
statement declares aline
variable that will receive one line of content at a time before it is added to the list.Read the content of the resource line by line by calling the readLine() method of the
BufferedReader
instance until nothing is returned. Inside the loop, add the content of the line to the list with thelines.add(line);
statement.Finally, return the completed list.
In case of an error, an IOException
will be triggered, to be dealt with in the calling function. We can now run the program and see it in action.
Running the program
Let's compile and run our RemoteContent program:
$ javac communication/RemoteContent.java $ java communication.RemoteContent Please enter a valid URL $ https://www.google.com Retrieved a resource of type: text/html; charset=ISO-8859-1 from https://www.google.com [<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="fr"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="OlUGaODHuncQU7RO/lUQRQ==">(function(){window.google={kEI:'zUEuXLqpCa-JlwTytKCwBg',kEXPI:'0,1353747,57,1957,1017,1406,697,528,731,325,293,569,262,349,30,524,367,336,806,95,236,309,183,2335433,232,32,68,329226,1294,12383,4855,32691,15248,867,12163,16521,364,3319,1262,4243,2439,263,3663,1444,575,835,284,2,1306,2432,1361,4323,3398,296,1239,35,291,482,2115,137,2818,1529,920,626,2,1968,525,2067,182,283,556,596,1687,297,669,1050,464,1032,312,386,743,268,81,7,28,447,18,618,29,992,387,16,442,16,1847,91,1266,643,4604,876,412,2,554,2635,547,119,948,1220,38,363,259,11,287,269,304,145,155,498,719,1325,39,101,383,47,552,4,19,1,504,2369,367,790,9,2,13,245,499,1196,49,258,2,366,265,218,1219,825,300,2,4,2,670,44,18,31,1730,408,189,63,97,249,99,148,1117,145,168,97,724,22,479,104,1,485,1017,631,189,275,87,302,304,257,6,38,52,279,135,267,37,55,62,65,41,432,21,572,2,83,340,13,49,555,960,392,5970684,1874,680,235,11,5997355,90,2800095,4,1572,549,332,445,1,2,80,1,506,394,577,11,308,1,8,1,2,2132,1,1,1,1,1,414,1,748,141,59,341,10,2,373,3,7,362,81,3,117,1,2,140,8,125,29,64,33,7',authuser:0,kscs:'c9c918f0_zUEuXLqpCa-JlwTytKCwBg',kGL:'FR'};google.kHL='fr';})();google.time=function(){return(new Date).getTime()};(function(){google.lc=[];google.li=0;google.getEI=function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||google.kEI};google.getLEI=function(a){for(var b=null;a&&(!a.getAttribute||!(b=a.getAttribute("leid")));)a=a.parentNode;return b};google.https=function(){return"https:"==window.location.protocol};google.ml=function(){return null};google.log=function(a,b,e,c,g){if(a=google.logUrl(a,b,e,c,g)){b=new Image;var d=google.lc,f=google.li;d[f]=b;b.onerror=b.onload=b.onabort=function(){delete d[f]};google.vel&&google.vel.lu&&google.vel.lu(a);b.src=a;google.li=f+1}};google.logUrl=function(a,b,e,c,g){var d="",f=google.ls||"";e||-1!=b.search("&ei=")||(d="&ei="+google.getEI(c),-1==b.search("&lei=")&&(c=google.getLEI(c))&&(d+="&lei="+c));c="";!e&&google.cshid&&-1==b.search("&cshid=")&&"slh"!=a&&(c="&cshid="+google.cshid);a=e||"/"+(g||"gen_204")+"?atyp=i&ct="+a+"&cad="+b+d+f+"&zx="+google.time()+c;/^http:/i.test(a)&&google.https()&&(google.ml(Error("a"),!1,{src:a,glmm:1}),a="");return a};}).call(this);(function(){google.y={};google.x=function(a,b){if(a)var c=a.id;else{do c=Math.random();while(google.y[c])}google.y[c]=[a,b];return!1};google.lm=[];google.plm=function(a){google.lm.push.apply(google.lm,a)};google.lq=[];google.load=function(a,b,c){google.lq.push([[a],b,c])};google.loadAll=function(a,b){google.lq.push([a,b])};}).call(this);google.f={};</script><script nonce="OlUGaODHuncQU7RO/lUQRQ==">var a=window.location,b=a.href.indexOf("#");if(0<=b){var c=a.href.substring(b+1);/(^|&)q=/.test(c)&&-1==c.indexOf("#")&&a.replace("/search?"+c.replace(/(^|&)fp=[^&]*/g,"")+"&cad=h")};</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}, </style><style>body,td,a,p,.h{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.h{color:#36c}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}body{background:#fff;color:black}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff !important}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px}.lsbb{display:block}.ftl,#fll a{display:inline-block;margin:0 12px}.lsb{background:url(/images/nav_logo229.png) 0 -261px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}</style><script nonce="OlUGaODHuncQU7RO/lUQRQ=="></script></head><body bgcolor="#fff"><script nonce="OlUGaODHuncQU7RO/lUQRQ==">(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}, if (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}, }, })();</script><div id="mngb"> <div id=gbar><nobr><b class=gb1>Recherche</b> <a class=gb1 href="https://www.google.fr/imghp?hl=fr&tab=wi">Images</a> <a class=gb1 href="https://maps.google.fr/maps?hl=fr&tab=wl">Maps</a> <a class=gb1 href="https://play.google.com/?hl=fr&tab=w8">Play</a> <a class=gb1 href="https://www.youtube.com/?gl=FR&tab=w1">YouTube</a> <a class=gb1 href="https://news.google.fr/nwshp?hl=fr&tab=wn">Actualit?s</a> <a class=gb1 href="https://mail.google.com/mail/?tab=wm">Gmail</a> <a class=gb1 href="https://drive.google.com/?tab=wo">Drive</a> <a class=gb1 style="text-decoration:none" href="https://www.google.fr/intl/fr/about/products?tab=wh"><u>Plus</u> »</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href="http://www.google.fr/history/optout?hl=fr" class=gb4>Historique Web</a> | <a href="/preferences?hl=fr" class=gb4>Param?tres</a> | <a target=_top id=gb_70 href="https://accounts.google.com/ServiceLogin?hl=fr&passive=true&continue=https://www.google.com/" class=gb4>Connexion</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div> </div><center><br clear="all" id="lgpd"><div id="lga"><img alt="Google" height="92" src="/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png" style="padding:28px 0 14px" width="272" id="hplogo" onload="window.lol&&lol()"><br><br></div><form action="/search" name="f"><table cellpadding="0" cellspacing="0"><tr valign="top"><td width="25%"> </td><td align="center" nowrap=""><input name="ie" value="ISO-8859-1" type="hidden"><input value="fr" name="hl" type="hidden"><input name="source" type="hidden" value="hp"><input name="biw" type="hidden"><input name="bih" type="hidden"><div class="ds" style="height:32px;margin:4px 0"><input style="color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top" autocomplete="off" class="lst" value="" title="Recherche Google" maxlength="2048" name="q" size="57"></div><br style="line-height:0"><span class="ds"><span class="lsbb"><input class="lsb" value="Recherche Google" name="btnG" type="submit"></span></span><span class="ds"><span class="lsbb"><input class="lsb" value="J'ai de la chance" name="btnI" onclick="if(this.form.q.value)this.checked=1; else top.location='/doodles/'" type="submit"></span></span></td><td class="fl sblc" align="left" nowrap="" width="25%"><a href="/advanced_search?hl=fr&authuser=0">Recherche avanc?e</a><a href="/language_tools?hl=fr&authuser=0">Outils linguistiques</a></td></tr></table><input id="gbv" name="gbv" type="hidden" value="1"><script nonce="OlUGaODHuncQU7RO/lUQRQ==">(function(){var a,b="1";if(document&&document.getElementById)if("undefined"!=typeof XMLHttpRequest)b="2";else if("undefined"!=typeof ActiveXObject){var c,d,e=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];for(c=0;d=e[c++];)try{new ActiveXObject(d),b="2"}catch(h){}}a=b;if("2"==a&&-1==location.search.indexOf("&gbv=2")){var f=google.gbvu,g=document.getElementById("gbv");g&&(g.value=a);f&&window.setTimeout(function(){location.href=f},0)};}).call(this);</script></form><div id="gac_scont"></div><div style="font-size:83%;min-height:3.5em"><br></div><span id="footer"><div style="font-size:10pt"><div style="margin:19px auto;text-align:center" id="fll"><a href="/intl/fr/ads/">Solutions publicitaires</a><a href="/services/">Solutions d'entreprise</a><a href="https://plus.google.com/106901486880272202822" rel="publisher">+Google</a><a href="/intl/fr/about.html">? propos de Google</a><a href="https://www.google.com/setprefdomain?prefdom=FR&prev=https://www.google.fr/&sig=K_eoz9rsbMMH_8RvGm5ovpVORa-Gw%3D">Google.fr</a></div></div><p style="color:#767676;font-size:8pt">© 2019 - <a href="/intl/fr/policies/privacy/">Confidentialit?</a> - <a href="/intl/fr/policies/terms/">Conditions</a></p></span></center><script nonce="OlUGaODHuncQU7RO/lUQRQ==">(function(){window.google.cdo={height:0,width:0};(function(){var a=window.innerWidth,b=window.innerHeight;if(!a||!b){var c=window.document,d="CSS1Compat"==c.compatMode?c.documentElement:c.body;a=d.clientWidth;b=d.clientHeight}a&&b&&(a!=google.cdo.width||b!=google.cdo.height)&&google.log("","","/client_204?&atyp=i&biw="+a+"&bih="+b+"&ei="+google.kEI);}).call(this);})();(function(){var u='/xjs/_/js/k\x3dxjs.hp.en.-PpIeOYp7rw.O/m\x3dsb_he,d/am\x3dYsAs/rt\x3dj/d\x3d1/rs\x3dACT90oHak6Vea8_d5yZnUPgd2x9xqhMspg';var b={gen204:"xjsls",clearcut:31};setTimeout(function(){var a=document.createElement("script");a.src=u;google.timers&&google.timers.load&&google.tick&&google.tick("load",b);document.body.appendChild(a)},0);})();(function(){window.google.xjsu='/xjs/_/js/k\x3dxjs.hp.en.-PpIeOYp7rw.O/m\x3dsb_he,d/am\x3dYsAs/rt\x3dj/d\x3d1/rs\x3dACT90oHak6Vea8_d5yZnUPgd2x9xqhMspg';})();function _DumpException(e){throw e;}, (function(){var pmc='{\x22Qnk92g\x22:{},\x22U5B21g\x22:{},\x22YFCs/g\x22:{},\x22ZI/YVQ\x22:{},\x22d\x22:{},\x22sb_he\x22:{\x22agen\x22:true,\x22cgen\x22:true,\x22client\x22:\x22heirloom-hp\x22,\x22dh\x22:true,\x22dhqt\x22:true,\x22ds\x22:\x22\x22,\x22ffql\x22:\x22fr\x22,\x22fl\x22:true,\x22host\x22:\x22google.com\x22,\x22isbh\x22:28,\x22jsonp\x22:true,\x22lm\x22:true,\x22msgs\x22:{\x22cibl\x22:\x22Effacer la recherche\x22,\x22dym\x22:\x22Essayez avec cette orthographe :\x22,\x22lcky\x22:\x22J\\u0026#39;ai de la chance\x22,\x22lml\x22:\x22En savoir plus\x22,\x22oskt\x22:\x22Outils de saisie\x22,\x22psrc\x22:\x22Cette suggestion a bien ?t? supprim?e de votre \\u003Ca href\x3d\\\x22/history\\\x22\\u003Ehistorique Web\\u003C/a\\u003E.\x22,\x22psrl\x22:\x22Supprimer\x22,\x22sbit\x22:\x22Recherche par image\x22,\x22srch\x22:\x22Recherche Google\x22},\x22ovr\x22:{},\x22pq\x22:\x22\x22,\x22refpd\x22:true,\x22rfs\x22:[],\x22sbpl\x22:24,\x22sbpr\x22:24,\x22scd\x22:10,\x22sce\x22:5,\x22stok\x22:\x22Z_5U_phZH7hRgjf72aMUrI4yxVE\x22,\x22uhde\x22:false}}';google.pmc=JSON.parse(pmc);})();(function(){var r=['aa','async','ipv6','mu','sf'];google.plm(r);})();</script> </body></html>]
It works! Let's complete our work by saving the content to a file for easier inspection.
Generate a text file
In this last section of this chapter, we will save our resource content into a file. We will create another class that will make use of our RemoteContent class and add the functionality. Here is the code for the class definition and the main function:
The main function is very similar to the last program. We just add a call to a function that will write to a file:
package communication;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.util.List;
/**
* Demo of writing to a text file
*
* @author the OpenClassrooms Education Team
*
*/
public class WriteFile {
/**
* Connect to a resource from a URL and print its content type
* @param args not used in this example
*/
public static void main(String[] args){
// define the string representation of the URL to connect to
String urlString=UserInput.askForUrl();
// connect and print the content type of the retrieved resource
try {
URLConnection myURLConnection=RemoteContent.connectFromURL(urlString);
List<String> content= RemoteContent.getContent(myURLConnection);
writeToFile(content, "output.txt");
}
// manage errors if the connection fails
catch (MalformedURLException e) {
System.err.println("Malformed URL - " + e.getLocalizedMessage());
}
catch(IOException e){
System.err.println("Cannot establish connection - "+ e.toString());
}
}
The file writing takes place if the connection works, thanks to a call to the writeToFile method. Here is the code:
/** writes the content of a list of strings to a file
*
* @param content the list of strings
* @param fileName the name of the output file
*/
public static void writeToFile(List<String> content, String fileName) {
Path pathToFile= Paths.get(fileName);
try (BufferedWriter writer = Files.newBufferedWriter(pathToFile)){
for(String line: content) {
writer.write(line);
}
System.out.println("Content written to " + pathToFile );
} catch (IOException e) {
System.out.println("Could not write file to " + pathToFile);
e.printStackTrace();
}
}
All the file management is done through the Files.newBufferedWriter method that creates an instance of a BufferedWriter. Each call to the write method of that object adds a line to the file given as argument.
After running this code, the content of a valid and reachable URL should be available to you in the generated output.txt file.
Summary
In this chapter, you've learned the following:
Networking is managing a request-response combination over the network which is typically the internet. Networking implies working with URLs.
In Java, the following components are used to implement the URL connection:
URL
- the class used to define a URL objectURLConnection
- a class with methods related to URLsThe
BufferedReader
andBufferedWriter
classes provide an efficient way to read and write to external resources