abel
asked on
Challenge: getting directory listing using URLConnection
Hi there!
Some http-servers allow clients to get the directory listing of a specific directory if there's no default html page. The question is easy: how can I get that listing using Java?
It's quite easy getting a page, below you see the code needed for doing that. Just as soon as I try to use a URL which is a directory I get an iContentsize of -1, which is not much, is it?
Below is the code I use in a slightly moderated form. The parts of interest are between "start-" and "end important part". The authorization part is borrowed from Q.10009989 ("Retrieval of URL with Authorization") as is the HTUU-class. Of course, this is not needed for most sites.
Who can/want to help me with this challenge? Maybe it's quite easy, but then you're just lucky getting the points. Any answer which really gets me such a listing will get the credits.
PS: I use SilverStream, in case you were wondering about the AgoInvokedEvent. The method uses "evt.setResult()" for setting data for the calling thread.
Greetz and thanks in advance,
Abel
public void invoked(AgoInvokedEvent evt) throws Exception
{
Hashtable htResultData = new Hashtable();
try
{
//////////////the important part/////////////////////
URLConnection ucToGet = (new URL("http://host/path")).openConnection();
ucToGet.setRequestProperty ("Authoriz ation", "Basic " + HTUU.encode("user:password "));
InputStream is = ucToGet.getInputStream();
int iContentSize = ucToGet.getContentLength() ;
if(iContentSize < 1) //Can't do anything in this case: a directory
throw new Exception("Contentlength is smaller then one, can't read content! (Directorylisting)");
///////////////end important part////////////////////
byte bData[] = new byte[iContentSize];
int b = 0, x = 0;
while ((b = is.read()) != -1 && (x < iContentSize))
{
bData[x++]=(byte) b;
}
htResultData.put("size", new Integer(iContentSize));
htResultData.put("data", bData);
htResultData.put("result", SUCCEED);
if(DEBUG) System.out.println("SUCCEE D gezet");
}
catch(Exception __E)
{
if(__E instanceof FileNotFoundException)
htResultData.put("descript ion", "The URL has not been found on the server, " +
"couldn't retrieve the URL, please try again with another URL.\n\n" +
"Some other reason for this error maybe a malformed loginname/password combination.");
else
htResultData.put("descript ion", ""); //means caller should use "error"
htResultData.put("result", ERROR);
htResultData.put("error", __E); //Store error for retrieval for the caller
}
finally
{
evt.setResult(htResultData );
return;
}
}
Some http-servers allow clients to get the directory listing of a specific directory if there's no default html page. The question is easy: how can I get that listing using Java?
It's quite easy getting a page, below you see the code needed for doing that. Just as soon as I try to use a URL which is a directory I get an iContentsize of -1, which is not much, is it?
Below is the code I use in a slightly moderated form. The parts of interest are between "start-" and "end important part". The authorization part is borrowed from Q.10009989 ("Retrieval of URL with Authorization") as is the HTUU-class. Of course, this is not needed for most sites.
Who can/want to help me with this challenge? Maybe it's quite easy, but then you're just lucky getting the points. Any answer which really gets me such a listing will get the credits.
PS: I use SilverStream, in case you were wondering about the AgoInvokedEvent. The method uses "evt.setResult()" for setting data for the calling thread.
Greetz and thanks in advance,
Abel
public void invoked(AgoInvokedEvent evt) throws Exception
{
Hashtable htResultData = new Hashtable();
try
{
//////////////the important part/////////////////////
URLConnection ucToGet = (new URL("http://host/path")).openConnection();
ucToGet.setRequestProperty
InputStream is = ucToGet.getInputStream();
int iContentSize = ucToGet.getContentLength()
if(iContentSize < 1) //Can't do anything in this case: a directory
throw new Exception("Contentlength is smaller then one, can't read content! (Directorylisting)");
///////////////end important part////////////////////
byte bData[] = new byte[iContentSize];
int b = 0, x = 0;
while ((b = is.read()) != -1 && (x < iContentSize))
{
bData[x++]=(byte) b;
}
htResultData.put("size", new Integer(iContentSize));
htResultData.put("data", bData);
htResultData.put("result",
if(DEBUG) System.out.println("SUCCEE
}
catch(Exception __E)
{
if(__E instanceof FileNotFoundException)
htResultData.put("descript
"couldn't retrieve the URL, please try again with another URL.\n\n" +
"Some other reason for this error maybe a malformed loginname/password combination.");
else
htResultData.put("descript
htResultData.put("result",
htResultData.put("error", __E); //Store error for retrieval for the caller
}
finally
{
evt.setResult(htResultData
return;
}
}
ASKER
AND IT WORKS INSTANTLY!!
Thanks!
Your solution sounds so logical and is so easy to comprehend and apply that you definitely deserve the points, although you posted as a comment. Do you want to post again as an answer? Then I can grade you well :)
It's probably due to my short time in Java-world that I need to learn these quite logical things.
Once again, thanks for this quick reply!
greetz,
Abel
Thanks!
Your solution sounds so logical and is so easy to comprehend and apply that you definitely deserve the points, although you posted as a comment. Do you want to post again as an answer? Then I can grade you well :)
It's probably due to my short time in Java-world that I need to learn these quite logical things.
Once again, thanks for this quick reply!
greetz,
Abel
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for the tip :)
Bye!
Abel
Bye!
Abel
conetentLength = -1 means that server does not know the resource length, so you should read from the inputstream, until EOF.
InputStream is = ucToGet.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream (5000);
byte[] chunk = new byte[5000];
int len = is.read(chunk);
while (len >0)
{
os.write(chunk, 0, len);
len = is.read(chunk);
}
os.flush();
byte[] data = bos.toByteArray();