Как предотвратить 404 / java.io.FileNotFoundException при извлечении Java перенаправленного URL? - PullRequest
0 голосов
/ 17 декабря 2018

Мне нужно получить полный HTML-код страницы, созданной веб-службой Amazon.Мой вопрос связан с тем, почему я не могу получить этот html с серверов AWS.

Сервис AWS предоставляет начальный URL (URL # 1), который обычно обрабатывается браузером.URL # 1 возвращает статус 302 и URL перенаправленной страницы (URL # 2).

Это прекрасно работает, когда браузер работает с этими URL-адресами.Тем не менее, когда запускается наш код Java ниже, мы получаем статус 404 для URL-адреса № 2 и ошибку времени выполнения: java.io.FileNotFoundException: «URL-адрес № 2»

Вот код:

URL url = null;
HttpsURLConnection conHTTPS = null;
int nResponseCode = -999;
try {
    // Load url with URL #1.
    url = new URL("URL #1");

    conHTTPS = (HttpsURLConnection)url.openConnection();                        // create a Connection object for this URL but we don't actually connect yet
    conHTTPS.setInstanceFollowRedirects(false);                                 // without this we get a Status = 404 in getResponseCode() below on this initial URL!
    conHTTPS.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");    // try to make us "look like a browser"
    conHTTPS.setRequestProperty("Accept","*/*");
    conHTTPS.setRequestMethod("GET");
    // Java 7 defaults to TLS 1.0 so must do this before getResponseCode() or will throw with javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    SSLContext ssl = null;
    try {
        ssl = SSLContext.getInstance("TLSv1.2");
        ssl.init(null,null,new SecureRandom());
        }
    catch (final NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
        }
    conHTTPS.setSSLSocketFactory(ssl.getSocketFactory());                       // get this connection setup for TLS 1.2
    conHTTPS.connect();                                                         // actually connect to URL #1 (should be done by getResponseCode() but we do it to be sure)
    nResponseCode = conHTTPS.getResponseCode();                                 // nResponseCode is returned as 302 (a redirect)
    }
catch (final MalformedURLException e1) {
    e1.printStackTrace();
    }
catch (final IOException e1) {
    e1.printStackTrace();
    }

// Use the response to URL #1 to get the redirection URL #2.
URL urlRedir = null;
HttpsURLConnection conHTTPSRedir = null;
try {
    // The prior conHTTPS.connect(); returned the redir URL in the "Location" header so get it.
    final URL urlBase = conHTTPS.getURL();
    final String sLocation = conHTTPS.getHeaderField("Location");
    urlRedir = new URL(urlBase,sLocation);                                      // use these two parts to build URL #2
    conHTTPSRedir = (HttpsURLConnection)urlRedir.openConnection();
    conHTTPSRedir.setInstanceFollowRedirects(false);
    try {
        sslRedir = SSLContext.getInstance("TLSv1.2");
        sslRedir.init(null,null,new SecureRandom());
        }
    catch (final NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
        }
    conHTTPSRedir.setSSLSocketFactory(sslRedir.getSocketFactory());
    conHTTPSRedir.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
    conHTTPSRedir.setRequestProperty("Accept","*/*");
    conHTTPSRedir.setRequestMethod("GET");
    conHTTPSRedir.connect();
    nResponseCode = conHTTPSRedir.getResponseCode();                        // nResponseCode is returned as 404!
    final InputStream inputStream = conHTTPSRedir.getInputStream();         // consistent with the 404, this throws java.io.FileNotFoundException
    }
catch (final IOException e1) {
    // Get the html of the error page the AWS server returns.
    final InputStream is = conHTTPSRedir.getErrorStream();
    final String contentEncoding = conHTTPSRedir.getContentEncoding() != null ? conHTTPSRedir.getContentEncoding() : "UTF-8";
    final String sErrorPage = IOUtils.toString(is, contentEncoding); //Apache Commons IO
    }

Вот (единственная) информативная часть того, что sErrorPage из приведенного выше блока catch содержит:

The page you tried was not found.

You may have typed the address incorrectly or you may have used an outdated link.

Если я использую отладчик, шагаю по коду и останавливаюсь сразу после получения urlRedir ивручную взяв его значение и вставив его в браузер, мы увидим страницу как надо, поэтому этот URL №2 хорош и работает в браузере.Но если бы я позволил продолжить код, мы получили бы 404 для того же URL!

Кто-нибудь может объяснить, что здесь не так?

Спасибо.

...