URLConnection FileNotFoundException для нестандартных источников портов HTTP - PullRequest
23 голосов
/ 03 июня 2009

Я пытался использовать задачу Apache Ant Get , чтобы получить список WSDL, созданных другой командой в нашей компании. Они размещены на сервере weblogic 9.x по адресу http: //....com: 7925 / services / . Я могу попасть на страницу через браузер, но задача get выдает мне исключение FileNotFoundException при попытке скопировать страницу в локальный файл для анализа. Я все еще был в состоянии получить (используя задачу муравья) URL без нестандартного порта 80 для HTTP.

Я просмотрел исходный код Ant и сузил ошибку до URLConnection. Кажется, что URLConnection не распознает данные как трафик HTTP, так как они не находятся на стандартном порту, даже если протокол указан как HTTP. Я перехватил трафик с помощью WireShark, и страница корректно загружается по сети, но все еще получает исключение FileNotFoundException.

Вот пример, где вы увидите ошибку (с измененным URL-адресом для защиты невинных). Ошибка выдается на connection.getInputStream ();

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

    public class TestGet {
    private static URL source; 
    public static void main(String[] args) {
        doGet();
    }
    public static void doGet() {
            try {
            source = new URL("http", "test.com", 7925,
                    "/services/index.html");
            URLConnection connection = source.openConnection();
            connection.connect();
            InputStream is = connection.getInputStream();
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

}

Ответы [ 8 ]

46 голосов
/ 09 ноября 2010

Ответ на мой HTTP-запрос вернулся с кодом состояния 404, что привело к исключению FileNotFoundException, когда я вызвал getInputStream (). Я все еще хотел прочитать тело ответа, поэтому мне пришлось использовать другой метод: HttpURLConnection # getErrorStream () .

Вот фрагмент JavaDoc getErrorStream ():

Возвращает поток ошибок, если соединение не удалось, но сервер отправлен полезные данные тем не менее. Типичный Например, когда HTTP-сервер отвечает 404, что приведет к FileNotFoundException, который будет брошен в соединении, но сервер отправил HTML-страница справки с предложениями по что делать.

Пример использования:

public static String httpGet(String url) {
    HttpURLConnection con = null;
    InputStream is = null;
    try {
        con = (HttpURLConnection) new URL(url).openConnection();
        con.connect();

        //4xx: client error, 5xx: server error. See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
        boolean isError = con.getResponseCode() >= 400;
        //In HTTP error cases, HttpURLConnection only gives you the input stream via #getErrorStream().
        is = isError ? con.getErrorStream() : con.getInputStream();

        String contentEncoding = con.getContentEncoding() != null ? con.getContentEncoding() : "UTF-8";
        return IOUtils.toString(is, contentEncoding); //Apache Commons IO
    } catch (Exception e) {
        throw new IllegalStateException(e);
    } finally {
        //Note: Closing the InputStream manually may be unnecessary, depending on the implementation of HttpURLConnection#disconnect(). Sun/Oracle's implementation does close it for you in said method.
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        if (con != null) {
            con.disconnect();
        }
    }
}
19 голосов
/ 16 февраля 2010

Это старая ветка, но у меня была похожая проблема, и я нашел решение, которого здесь нет.

Я получал страницу нормально в браузере, но получил 404, когда пытался получить к ней доступ через HttpURLConnection. URL, к которому я пытался получить доступ, содержал номер порта. Когда я попробовал это без номера порта, я успешно получил фиктивную страницу через HttpURLConnection. Так что, похоже, проблема была в нестандартном порте.

Я начал думать, что доступ был ограничен, и в некотором смысле это было. Мое решение состояло в том, что мне нужно было сообщить серверу User-Agent, и я также указал ожидаемые типы файлов. Я пытаюсь прочитать файл .json, поэтому я подумал, что тип файла также может быть необходимой спецификацией.

Я добавил эти строки, и это наконец заработало:

httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
7 голосов
/ 03 июня 2009

проверить код ответа, возвращаемый сервером

2 голосов
/ 10 октября 2012

Я знаю, что это старая ветка, но я нашел решение, которое нигде не указано здесь.

Я пытался извлечь данные в формате json из сервлета J2EE через порт 8080, но получил сообщение об ошибке «Файл не найден». Мне удалось получить эти же данные JSON с php-сервера, работающего на порту 80.

Оказывается, в сервлете мне нужно было изменить doGet на doPost.

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 20 июля 2018

Вы можете использовать OkHttp :

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}
0 голосов
/ 10 октября 2013

Я знаю, что это старая ветка, но только что заметил что-то на этом, поэтому подумал, что я просто выложу ее там.

Как упоминалось Джессикой, это исключение выдается при использовании нестандартного порта.

Хотя, кажется, это происходит только при использовании DNS. Если я использую номер IP, я могу указать номер порта, и все работает нормально.

0 голосов
/ 30 ноября 2012

Я столкнулся с подобной проблемой, но причина, кажется, другая, вот трассировка исключения:

java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
    at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1491)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1485)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
    at com.doitnext.loadmonger.HttpExecution.getBody(HttpExecution.java:85)
    at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.java:214)
    at com.doitnext.loadmonger.ClientWorker.run(ClientWorker.java:126)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1434)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
    at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.java:166)
    ... 2 more

Так что может показаться, что простое получение кода ответа вызовет соединение URL с callGetInputStream.

0 голосов
/ 03 июня 2009

Я пробовал это локально - используя предоставленный код - и не получаю FileNotFoundException, за исключением случаев, когда сервер возвращает ответ о состоянии 404.

Вы уверены, что подключаетесь к веб-серверу, к которому собираетесь подключаться? Есть ли вероятность, что вы подключаетесь к другому веб-серверу? (Замечу, что номер порта в коде не совпадает с номером порта в ссылке)

...