简体   繁体   中英

FileNotFoundException from certain images over HTTP - Java

In a class that processes a list of images over HTTP, one image throws a FNFE. The first assumption would be that the file doesn't exist at the destination - but it does. The image is accessible in a browser and via another Java application (a command-line test case I wrote) running on the same machine?

Here's the stack trace:

23-Apr-2012 17:23:57 uk.co.example.ExampleClass setImageUrl
WARNING: Exception setting image Url to http://images.example.co.uk/FPA-Midlands/MLO100316_01.jpg
java.io.FileNotFoundException: http://images.example.co.uk/FPA-Midlands/MLO100316_01.jpg
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1311)
    at uk.co.example.ExampleClass.importFileFromUrl(ExampleClass.java:460)

This is the orginating code:

private String importFileFromUrl(String imageUrl) throws IOException, CMException {
    InputStream is = null;
    String name = null;
    if (imageUrl != null && imageUrl.startsWith("http")) {
        URL url = new URL(imageUrl);
        URLConnection urlc = url.openConnection();
        is = urlc.getInputStream();
        name = url.getFile();
        name = name.substring(name.lastIndexOf('/') + 1);
    } else if (StringUtils.isNotBlank(imageUrl)){
        File f = new File (imageUrl);
        name = f.getName();
        is = new FileInputStream(f);
    }
    if (name != null && is != null) {
        importFile(name, is);
    }
    return name;
}

Because the sun.net.www.protocol.http.HttpURLConnection class appears in the stack, I was wondering whether this is a classloader issue? I haven't explicitly imported that package - shouldn't it be using a java.net equivalent?

Are you using Sun/Oracle JDK or Open JDK? Could you please go to the console and insert here the output for "java -version" ?

I added a try/catch block around the getInputStream() call:

try {
    is = urlc.getInputStream();
} catch(FileNotFoundException fnfe){
    is = ((HttpURLConnection) urlc).getErrorStream();
    LOG.log(Level.WARNING, "Exception streaming image: \n" + IOUtils.toString(is));
    throw fnfe;
}

From the log output, it's now very clear that the server is responding with a 404 response code:

25-Apr-2012 10:46:43 uk.co.example.ExampleClass importFileFromUrl
WARNING: Exception streaming image: 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
~~~ snip ~~~
<h2>HTTP Error 404 - File or directory not found.<br>Internet Information Services (IIS)</h2>
~~~ snip ~~~

I wasn't previously aware of the getErrorStream() method - I'd assumed any page response would have been covered by getInputStream() . The other area I found confusing / unintuitive is that the HttpURLConnection class throws the FNFE for a HTTP 404 response .

For other errors, the response code is much more obvious:

13-Apr-2012 15:40:43 uk.co.example.ExampleClass setImageUrl
WARNING: Exception setting property image Url to http://images.example.co.uk/FPA-Midlands/MLO100316_01.jpg
java.io.IOException: Server returned HTTP response code: 403 for URL: http://images.example.co.uk/FPA-Midlands/MLO100316_01.jpg
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)

Since making the above change, the issue hasn't reoccurred. The only way I can explain it is that the browser must have been caching the image or that it was an intermittent problem. In any case, now the extra logging is available, any issue should be easy to resolve in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM