Próbuję wysłać żądanie wpisu do adresu URL za pomocą HttpURLConnection (do używania cUrl w java). Treść żądania to xml, a na końcu aplikacja przetwarza xml i przechowuje rekord w bazie danych, a następnie odsyła odpowiedź w postaci ciągu xml. Aplikacja jest hostowana lokalnie na apache-tomcat.
Kiedy wykonuję ten kod z terminala, wiersz zostanie dodany do bazy danych zgodnie z oczekiwaniami. Ale wyjątek jest zgłaszany w następujący sposób podczas pobierania InputStream z połączenia
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)
Oto kod
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();
}
}
}
Jest to mylące, ponieważ wyjątek jest śledzony w wierszu InputStream response = con.getInputStream();
i wydaje się, że nie ma żadnego pliku związanego z wyjątkiem FileNotFoundException.
Kiedy próbuję bezpośrednio otworzyć połączenie z plikiem xml, nie zgłasza tego wyjątku.
Aplikacja usługowa wykorzystuje Spring Framework i Jaxb2Marshaller do tworzenia odpowiedzi XML.
Klasa ReadWriteTextFile jest pobierana stąd
Dzięki.
Edycja: Cóż, zapisuje dane w bazie danych i odsyła kod statusu odpowiedzi 404 w tym samym czasie.
Spróbowałem też zrobić curl używając php i wydrukować, CURLINFO_HTTP_CODE
który okazuje się być 200.
Jakieś pomysły, jak mam to debugować? Usługa i klient znajdują się na serwerze lokalnym.
Rozwiązane: mogłem rozwiązać problem po zapoznaniu się z odpowiedzią dotyczącą samego SO.
Wygląda na to, że HttpURLConnection zawsze zwraca odpowiedź 404 podczas łączenia się z adresem URL z niestandardowym portem.
Dodanie tych linii rozwiązało problem
con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");
Odpowiedzi:
Nie wiem o twojej kombinacji Spring / JAXB, ale przeciętny serwis WWW REST nie zwróci treści odpowiedzi w POST / PUT, tylko status odpowiedzi . Chciałbyś to określić zamiast ciała.
Zastąpić
przez
Wszystkie dostępne kody stanu i ich znaczenie są dostępne w specyfikacji HTTP, zgodnie z wcześniejszym połączeniem. Sama usługa sieciowa powinna również zawierać dokumentację, która zawiera przegląd wszystkich kodów statusu obsługiwanych przez usługę sieciową i ich specjalne znaczenie, jeśli takie istnieje.
Jeśli stan zaczyna się od
4nn
lub5nn
,getErrorStream()
zamiast tego chcesz odczytać treść odpowiedzi, która może zawierać szczegóły błędu.źródło
getErrorStream()
. Zgłasza wyjątek NullPointerException nanew InputStreamReader(con.getErrorStream())
.URLConnection
problematyczne. Zastanawiam się, dlaczego faceci z Java nie zaimplementowali po prostugetInputStream()
wHttpUrlConnection
stylureturn responseCode == 200 ? super.getInputStream() : this.getErrorStream()
. Ale w każdym razie; informacyjna odpowiedź, +1.FileNotFound
to tylko niefortunny wyjątek używany do wskazania, że serwer WWW zwrócił błąd 404.źródło
getResponseCode()
zanim zadzwoniszgetInputStream()
.Dla każdego, kto będzie miał ten problem w przyszłości, powodem jest to, że kod statusu to 404 (lub w moim przypadku był to 500). Wygląda na to, że
InpuStream
funkcja zgłosi błąd, gdy kod stanu jest inny niż 200.W moim przypadku kontroluję swój własny serwer i zwracałem kod statusu 500, aby wskazać, że wystąpił błąd. Pomimo tego, że wysłałem również treść z komunikatem tekstowym opisującym błąd,
inputstream
wyrzuciłem błąd, niezależnie od tego , czy treść była całkowicie czytelna.Jeśli kontrolujesz swój serwer, przypuszczam, że można to załatwić, wysyłając sobie kod statusu 200, a następnie obsługując odpowiedź na błąd ciągu.
źródło
Dla każdego, kto się o to potyka, to samo przytrafiło mi się podczas próby wysłania nagłówka żądania SOAP do usługi SOAP. Problem polegał na złej kolejności w kodzie, najpierw zażądałem strumienia wejściowego przed wysłaniem treści XML. W poniższym wyciętym kodzie linia
InputStream in = conn.getInputStream();
pojawiła się bezpośrednio poByteArrayOutputStream out = new ByteArrayOutputStream();
której jest niepoprawna kolejność rzeczy.FileNotFound
w tym przypadku był to niefortunny sposób zakodowania kodu odpowiedzi HTTP 400.źródło
new ByteArrayOutputStream()
nie ma z tym w ogóle nic wspólnego. Problem dotyczy kolejności międzygetInputStream()
agetResponseCode()
.FileNotFound w tym przypadku oznacza, że otrzymałeś 404 z serwera - czy to możliwe, że serwer nie lubi żądań „POST”?
źródło
Rozwiązanie:
Wystarczy zmienić localhost dla IP komputera
, jeśli chcesz wiedzieć, to: Windows + R> cmd> ipconfig
przykład: http: // 192.168.0.107 /directory/service/program.php?action=sendSomething
prostu zastąpić 192.168 .0.107 dla własnego adresu IP (nie próbuj 127.0.0.1, ponieważ jest to to samo, co localhost )
źródło
Proszę zmień
Do
źródło