Ответ 1
проверить код ответа, возвращаемый сервером
Я пытался использовать задачу Apache Ant Get
, чтобы получить список WSDL, сгенерированных другой командой в нашей компании. Они размещены на сервере weblogic 9.x на http://....com:7925/services/. Я могу перейти на страницу через браузер, но задача get дает мне FileNotFoundException при попытке скопировать страницу в локальный файл для разбора. Я все еще мог получить (используя задачу Ant) 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());
}
}
}
проверить код ответа, возвращаемый сервером
Ответ на мой 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 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();
}
}
}
Это старый поток, но у меня была аналогичная проблема, и я нашел решение, которое здесь не указано.
Я получил страницу в браузере, но получил 404, когда попытался получить доступ к ней через HttpURLConnection. URL-адрес, который я пытался получить, содержал номер порта. Когда я попробовал это без номера порта, я успешно получил фиктивную страницу через HttpURLConnection. Таким образом, проблема была в нестандартном порту.
Я начал думать, что доступ ограничен, и в некотором смысле это было. Мое решение состояло в том, что мне нужно было сообщить серверу User-Agent, а также указать типы файлов, которые я ожидаю. Я пытаюсь прочитать файл .json, поэтому я думал, что тип файла также может быть необходимой спецификацией.
Я добавил эти строки и, наконец, работал:
httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
Я знаю, что это старый поток, но я нашел решение, не указанное здесь нигде.
Я пытался вытащить данные в формате json из сервлета J2EE на порт 8080, но получал ошибку, не найденную в файле. Я смог вытащить эти же json-данные с php-сервера, работающего на порту 80.
Оказывается, что в сервлете мне нужно было изменить doGet на doPost.
Надеюсь, это поможет кому-то.
Я пробовал это локально - используя предоставленный код - и я не получаю FileNotFoundException
, за исключением случаев, когда сервер возвращает ответ статуса 404.
Вы уверены, что подключаетесь к веб-серверу, на который собираетесь подключаться? Есть ли вероятность, что вы подключаетесь к другому веб-серверу? (Я отмечаю, что номер порта в коде не соответствует номеру порта в ссылке)
У меня возникла аналогичная проблема, но причина, по-видимому, различна: вот трасса исключений:
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-адреса к вызовуGetInputStream.
Я знаю, что это старый поток, но только что заметил что-то на этом, так что подумал, что я просто его выложу.
Как упоминает Джессика, это исключение возникает при использовании нестандартного порта.
Это происходит только при использовании DNS. Если я использую IP-номер, я могу указать номер порта, и все работает нормально.