Ich versuche, eine Post-Anfrage mit HttpURLConnection an eine URL zu senden (für die Verwendung von cUrl in Java). Der Inhalt der Anforderung ist XML. Am Endpunkt verarbeitet die Anwendung die XML-Datei, speichert einen Datensatz in der Datenbank und sendet dann eine Antwort in Form einer XML-Zeichenfolge zurück. Die App wird lokal auf Apache-Tomcat gehostet.
Wenn ich diesen Code vom Terminal aus ausführe, wird der Datenbank erwartungsgemäß eine Zeile hinzugefügt. Beim Abrufen des InputStream von der Verbindung wird jedoch eine Ausnahme wie folgt ausgelöst
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)
Hier ist der Code
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();
}
}
}
Es ist verwirrend, weil die Ausnahme auf die Zeile zurückgeführt wird InputStream response = con.getInputStream();
und anscheinend keine Datei für eine FileNotFoundException beteiligt ist.
Wenn ich versuche, eine Verbindung zu einer XML-Datei direkt herzustellen, wird diese Ausnahme nicht ausgelöst.
Die Service-App verwendet Spring Framework und Jaxb2Marshaller, um die Antwort-XML zu erstellen.
Die Klasse ReadWriteTextFile wird von hier übernommen
Vielen Dank.
Bearbeiten: Nun, es speichert die Daten in der Datenbank und sendet gleichzeitig einen 404-Antwortstatuscode zurück.
Ich habe auch versucht, eine Locke mit PHP zu machen und die auszudrucken CURLINFO_HTTP_CODE
die sich als 200 herausstellt.
Irgendwelche Ideen, wie ich das debuggen soll? Sowohl der Dienst als auch der Client befinden sich auf dem lokalen Server.
Behoben: Ich konnte das Problem lösen, nachdem ich mich auf eine Antwort bezogen hatte auf SO selbst verwiesen hatte.
Es scheint, dass HttpURLConnection immer eine 404-Antwort zurückgibt, wenn eine Verbindung zu einer URL mit einem nicht standardmäßigen Port hergestellt wird.
Das Hinzufügen dieser Zeilen löste das Problem
con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");
Antworten:
Ich weiß nichts über Ihre Spring / JAXB-Kombination, aber der durchschnittliche REST-Webservice gibt keinen Antworttext für POST / PUT zurück, sondern nur einen Antwortstatus . Sie möchten es anstelle des Körpers bestimmen.
Ersetzen
durch
Alle verfügbaren Statuscodes und ihre Bedeutung sind in der zuvor verlinkten HTTP-Spezifikation verfügbar. Der Webservice selbst sollte auch eine Dokumentation enthalten, in der alle vom Webservice unterstützten Statuscodes und gegebenenfalls ihre besondere Bedeutung aufgeführt sind.
Wenn der Status mit
4nn
oder beginnt5nn
, möchten SiegetErrorStream()
stattdessen den Antworttext lesen, der möglicherweise die Fehlerdetails enthält.quelle
getErrorStream()
wie vorgeschlagen. Es wird eine NullPointerException ausgelöstnew InputStreamReader(con.getErrorStream())
.URLConnection
problematisch macht. Ich frage mich , warum die Java Jungs einfach nicht umsetzengetInputStream()
inHttpUrlConnection
entlang der Linienreturn responseCode == 200 ? super.getInputStream() : this.getErrorStream()
. Aber wie auch immer; informative Antwort, +1.FileNotFound
ist nur eine unglückliche Ausnahme, die angibt, dass der Webserver eine 404 zurückgegeben hat.quelle
getResponseCode()
bevor Sie anrufengetInputStream()
.Für jeden, der dieses Problem in Zukunft hat, liegt der Grund darin, dass der Statuscode 404 (oder in meinem Fall 500) war. Es erscheint die
InpuStream
Funktion einen Fehler auslöst, wenn der Statuscode nicht 200 ist.In meinem Fall kontrolliere ich meinen eigenen Server und habe einen 500-Statuscode zurückgegeben, um anzuzeigen, dass ein Fehler aufgetreten ist. Obwohl ich auch einen Text mit einer String-Nachricht gesendet habe, die den Fehler detailliert beschreibt, ist der
inputstream
ausgelöst, unabhängig davon, ob der Body vollständig lesbar ist.Wenn Sie Ihren Server steuern, können Sie dies vermutlich tun, indem Sie sich einen 200-Statuscode senden und dann die Antwort auf einen Zeichenfolgenfehler behandeln.
quelle
Für alle anderen, die darüber stolpern, ist mir dasselbe passiert, als ich versucht habe, einen SOAP-Anforderungsheader an einen SOAP-Dienst zu senden. Das Problem war eine falsche Reihenfolge im Code. Ich habe zuerst den Eingabestream angefordert, bevor ich den XML-Text gesendet habe. In dem unten geschnippten Code kam die Zeile
InputStream in = conn.getInputStream();
unmittelbar danach,ByteArrayOutputStream out = new ByteArrayOutputStream();
was die falsche Reihenfolge der Dinge ist.FileNotFound
In diesem Fall war es eine unglückliche Möglichkeit, den HTTP-Antwortcode 400 zu codieren.quelle
new ByteArrayOutputStream()
hat damit überhaupt nichts zu tun. Das Problem ist die Reihenfolge zwischengetInputStream()
undgetResponseCode()
.FileNotFound bedeutet in diesem Fall, dass Sie einen 404 von Ihrem Server erhalten haben. Könnte es sein, dass der Server keine "POST" -Anfragen mag?
quelle
Die Lösung:
Ändern Sie einfach localhost für die IP Ihres PCs,
wenn Sie dies wissen möchten: Windows + r> cmd> ipconfig
Beispiel: http: // 192.168.0.107 /directory/service/program.php?action=sendSomething
ersetzen Sie einfach 192.168 .0.107 für Ihre eigene IP (versuchen Sie nicht 127.0.0.1, da es mit localhost identisch ist )
quelle
Bitte austauschen
Zu
quelle