FileNotFoundException al obtener el objeto InputStream de HttpURLConnection

Estoy tratando de enviar una solicitud postal a una url usando HttpURLConnection (para usar cUrl en java). El contenido de la solicitud es xml y, en el punto final, la aplicación procesa el xml y almacena un registro en la base de datos y luego envía una respuesta en forma de cadena xml. La aplicación está alojada en apache-tomcat localmente.

Cuando ejecuto este código desde el terminal, se agrega una fila a la base de datos como se esperaba. Pero se lanza una excepción de la siguiente manera al obtener el InputStream de la conexión

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) 

Aquí está el código

 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 confuso porque la excepción se remonta a la línea InputStream response = con.getInputStream(); y no parece haber ningún archivo involucrado para una excepción FileNotFoundException.

Cuando bash abrir una conexión a un archivo xml directamente, no lanza esta excepción.

La aplicación de servicio usa Spring framework y Jaxb2Marshaller para crear el xml de respuesta.

La clase ReadWriteTextFile se toma de aquí

Gracias.

Editar: Bueno, guarda los datos en la base de datos y envía un código de estado de respuesta 404 al mismo tiempo.

También intenté hacer un curl usando php e imprimir el CURLINFO_HTTP_CODE que resulta ser 200.

¿Alguna idea sobre cómo hago para depurar esto? Tanto el servicio como el cliente están en el servidor local.

Resuelto: Pude resolver el problema después de referirme a una respuesta en el SO mismo.

Parece que HttpURLConnection siempre devuelve una respuesta 404 cuando se conecta a una url con un puerto no estándar.

Agregar estas líneas lo resolvió

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

No sé sobre su combinación Spring / JAXB, pero el servicio web REST promedio no devolverá un cuerpo de respuesta en POST / PUT, solo un estado de respuesta . Te gustaría determinarlo en lugar del cuerpo.

Reemplazar

 InputStream response = con.getInputStream(); 

por

 int status = con.getResponseCode(); 

Todos los códigos de estado disponibles y su significado están disponibles en la especificación HTTP, como vinculados anteriormente. El servicio web en sí también debe venir junto con cierta documentación que revise todos los códigos de estado admitidos por el servicio web y su significado especial, en su caso.

Si el estado comienza con 4nn o 5nn , le gustaría usar getErrorStream() para leer el cuerpo de la respuesta que puede contener los detalles del error.

 InputStream error = con.getErrorStream(); 

FileNotFound es solo una desafortunada excepción utilizada para indicar que el servidor web devolvió un 404.

Para cualquier persona con este problema en el futuro, la razón es porque el código de estado era un 404 (o en mi caso era un 500). Parece que la función InpuStream arrojará un error cuando el código de estado no sea 200.

En mi caso, controlo mi propio servidor y estaba devolviendo un código de estado de 500 para indicar que ocurrió un error. A pesar de que también envié un cuerpo con un mensaje de cadena que detalla el error, el inputstream arrojó un error independientemente de que el cuerpo sea completamente legible.

Si controlas tu servidor, supongo que esto se puede manejar enviándote un código de estado 200 y luego manejando cualquier respuesta de error de cadena.

Para cualquier otra persona que tropiece con esto, me pasó lo mismo al tratar de enviar un encabezado de solicitud SOAP a un servicio SOAP. El problema era un orden incorrecto en el código, solicité el flujo de entrada primero antes de enviar el cuerpo XML. En el código recortado a continuación, la línea InputStream in = conn.getInputStream(); vino inmediatamente después de ByteArrayOutputStream out = new ByteArrayOutputStream(); que es el orden incorrecto de las cosas.

 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 en este caso fue una forma desafortunada de codificar el código de respuesta HTTP 400.

FileNotFound en este caso significa que obtuvo un 404 de su servidor, ¿podría ser que el servidor no le gusta las solicitudes “POST”?

La solución:
simplemente cambie localhost por la IP de su PC
si quieres saber esto: Windows + r> cmd> ipconfig
ejemplo: http: // 192.168.0.107 /directory/service/program.php?action=sendSomething
simplemente reemplace 192.168.0.107 por su propia IP (no intente con 127.0.0.1 porque es lo mismo que localhost )

Por favor cambia

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

A

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