FileNotFoundException при получении объекта InputStream из HttpURLConnection - PullRequest
92 голосов
/ 21 марта 2011

Я пытаюсь отправить почтовый запрос на URL, используя HttpURLConnection (для использования cUrl в java). Содержимое запроса - xml, и в конце приложение обрабатывает xml и сохраняет запись в базе данных, а затем отправляет ответ в виде строки xml. Приложение размещено на Apache-Tomcat локально.

Когда я выполняю этот код из терминала, в базу данных добавляется строка, как и ожидалось. Но исключение выдается следующим образом при получении InputStream из соединения

java.io.FileNotFoundException: http://localhost:8080/myapp/service/generate
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1401)
    at org.kodeplay.helloworld.HttpCurl.main(HttpCurl.java:30)

Вот код

public class HttpCurl {
    public static void main(String [] args) {

        HttpURLConnection con;

        try {
            con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);

            File xmlFile = new File("test.xml");

            String xml = ReadWriteTextFile.getContents(xmlFile);                

            con.getOutputStream().write(xml.getBytes("UTF-8"));
            InputStream response = con.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(response));
            for (String line ; (line = reader.readLine()) != null;) {
                System.out.println(line);
            }
            reader.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  }

Это сбивает с толку, потому что исключение прослеживается до строки InputStream response = con.getInputStream();, и, похоже, нет никакого файла, связанного с FileNotFoundException.

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

Сервисное приложение использует Spring Framework и Jaxb2Marshaller для создания XML-ответа.

Класс ReadWriteTextFile взят из здесь

Спасибо.

Edit: Что ж, он сохраняет данные в БД и одновременно отправляет код состояния ответа 404.

Я также попытался сделать локон с помощью php и распечатать CURLINFO_HTTP_CODE, который оказывается равным 200.

Есть идеи, как мне отладить это? И сервис, и клиент находятся на локальном сервере.

Решено: Я мог бы решить проблему после обращения к ответу на самом SO.

Кажется, HttpURLConnection всегда возвращает ответ 404 при подключении к URL с нестандартным портом.

Добавление этих строк решило проблему

con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");

Ответы [ 7 ]

120 голосов
/ 21 марта 2011

Я не знаю о вашей комбинации Spring / JAXB, но средний веб-сервис REST не будет возвращать тело ответа на POST / PUT, только статус ответа .Вы хотите определить его вместо тела.

Заменить

InputStream response = con.getInputStream();

на

int status = con.getResponseCode();

Все доступные коды состояния и их значения доступны в HTTPспецификация, как указано выше.Сам веб-сервис также должен сопровождаться некоторой документацией, в которой содержится обзор всех кодов состояния, поддерживаемых веб-сервисом, и их особое значение, если таковое имеется.

Если статус начинается с 4nn или 5nn, вам нужновместо этого использовать getErrorStream() для чтения тела ответа, которое может содержать подробности ошибки.

InputStream error = con.getErrorStream();
46 голосов
/ 21 марта 2011

FileNotFound - просто неудачное исключение, используемое для указания того, что веб-сервер возвратил 404.

28 голосов
/ 25 мая 2014

Для любого, кто столкнется с этой проблемой в будущем, причина в том, что код состояния был 404 (или в моем случае был 500).Похоже, что функция InpuStream выдаст ошибку, если код состояния не равен 200.

В моем случае я управляю своим собственным сервером и возвращаю код состояния 500, чтобы указать, что произошла ошибка.Несмотря на то, что я также отправлял тело со строковым сообщением с подробным описанием ошибки, inputstream выдал ошибку независимо от того, что тело полностью читаемо.

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

5 голосов
/ 10 марта 2014

Для всех, кто остался спотыкаться об этом, то же самое случилось со мной при попытке отправить заголовок запроса SOAP в службу SOAP.Проблема была в неправильном порядке в коде, я сначала запросил поток ввода перед отправкой тела XML.В приведенном ниже коде строка InputStream in = conn.getInputStream(); появилась сразу после ByteArrayOutputStream out = new ByteArrayOutputStream();, что является неправильным порядком вещей.

ByteArrayOutputStream out = new ByteArrayOutputStream();
// send SOAP request as part of HTTP body 
byte[] data = request.getHttpBody().getBytes("UTF-8");
conn.getOutputStream().write(data); 

if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
  Log.d(TAG, "http response code is " + conn.getResponseCode());
  return null;
}

InputStream in = conn.getInputStream();

FileNotFound в этом случае было неудачным способом кодирования HTTP-кода ответа 400.

4 голосов
/ 21 марта 2011

FileNotFound в данном случае означает, что вы получили 404 с вашего сервера - может ли сервер не любить запросы POST?

0 голосов
/ 13 августа 2016

Решение:
просто измените localhost для IP вашего ПК
, если вы хотите знать это: Windows+ r> cmd> ipconfig
пример: http://192.168.0.107/directory/service/program.php?action=sendSomething
просто замените 192.168.0.107 на свой собственный IP (не пытайтесь 127.0.0.1 , потому чтоэто так же, как localhost )

0 голосов
/ 29 января 2016

Пожалуйста, измените

con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection();

на

con = (HttpURLConnection) new URL("http://YOUR_IP:8080/myapp/service/generate").openConnection();
...