2009-06-02 22 views
23

Estaba intentando utilizar Apache Ant Get task para obtener una lista de WSDL generados por otro equipo de nuestra empresa. Los tienen alojados en un servidor wexical 9.x en http://....com:7925/services/. Puedo acceder a la página a través de un navegador, pero la tarea get me da una excepción FileNotFoundException cuando intento copiar la página a un archivo local para analizar. Todavía pude obtener (utilizando la tarea ant) ​​una URL sin el puerto 80 no estándar para HTTP.URLConnection FileNotFoundException para orígenes de puerto HTTP no estándar

Miré a través del código fuente de Ant y reduje el error a URLConnection. Parece que URLConnection no reconoce que los datos son tráfico HTTP, ya que no están en el puerto estándar, aunque el protocolo se especifique como HTTP. Detecté el tráfico con WireShark y la página se carga correctamente a través del cable, pero todavía recibe la excepción FileNotFoundException.

Aquí hay un ejemplo en el que verá el error (con la URL modificada para proteger a los inocentes). El error se produce en 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()); 
     } 
    } 

} 
+0

Ahora supongo que es un tipo pero su enlace está en el puerto 7924 y su código está mirando en el puerto 7925 – Gandalf

+0

Sí, era un error tipográfico, corregido ahora, gracias. – jeffl8n

Respuesta

7

verificación del código de respuesta que se devuelve por el servidor

+0

El servidor que estoy probando me da un código de estado de 200. – jeffl8n

+0

¿Cómo lo está verificando? – objects

+0

Lo estaba comprobando con Firefox. Sin embargo, tienes razón. El problema era que el servidor devolvía un código 404 al código Java, pero luego mostraba el índice de WSDL disponibles y, por lo tanto, respondía con un código de estado 200 OK a Firefox. Creo que es el comportamiento predeterminado de XFire para mostrar la lista de WSDL cuando hay un error 404. – jeffl8n

0

He intentado que localmente - utilizando el código proporcionado - y no obtener una FileNotFoundException excepto cuando el servidor devuelve una respuesta de estado 404.

¿Estás seguro de que te estás conectando al servidor web al que deseas conectarte? ¿Hay alguna posibilidad de que te conectes a un servidor web diferente? (Me cuenta que el número de puerto en el código no coincide con el número de puerto en el enlace)

+0

El servidor que estoy probando me da un código de estado de 200. El ejemplo de código anterior no tiene una URL válida porque no sabía de un servidor HTTP público que no sea puerto 80. – jeffl8n

+1

402 también dio esta excepción. – Pijusn

+0

También 503 da esta excepción (la mía hecha por una protección Anti-DDoS) –

19

Se trata de un viejo hilo, pero tuve un problema similar y encontré una solución que no está en la lista aquí.

Estaba recibiendo la página bien en el navegador, pero obtuve un 404 cuando traté de acceder a través de HttpURLConnection. La URL a la que intentaba acceder contenía un número de puerto. Cuando lo probé sin el número de puerto conseguí una página falsa con éxito a través de HttpURLConnection. Por lo que parecía que el puerto no estándar era el problema.

Empecé a pensar que el acceso estaba restringido, y en cierto sentido lo era. Mi solución fue que necesitaba decirle al servidor el User-Agent y también especifiqué los tipos de archivos que esperaba. Intento leer un archivo .json, así que pensé que el tipo de archivo también podría ser una especificación necesaria.

que añaden estas líneas y finalmente funcionó:

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

¡Muchas gracias, funciona! –

+0

Este era exactamente el problema al que me enfrentaba. Tu solución ayudó. Gracias una tonelada. – naiquevin

44

La respuesta a mi solicitud HTTP devuelto con un código de estado 404, lo que resultó en un FileNotFoundException cuando llamé getInputStream(). Todavía quería leer el cuerpo de la respuesta, así que tuve que usar un método diferente: HttpURLConnection # getErrorStream().

He aquí un fragmento de JavaDoc getErrorStream():

Devuelve el flujo de error si la conexión no pero el servidor envía datos útiles, no obstante. La típica ejemplo es cuando un servidor HTTP responde con un 404, lo que provocará un FileNotFoundException a ser lanzado en de conexión, pero el servidor envía una página HTML con ayuda sugerencias en cuanto a qué hacer.

Ejemplo de uso:

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's 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(); 
     } 
    } 
} 
+0

esto fue útil, pero es solo una vaga página de error de 400. Estoy usando https://graph.facebook.com/me/photos y en el navegador funciona a menos que intente ver los encabezados a través del complemento de desarrollador web. Entonces parece que el inputstream está creando una nueva solicitud de alguna manera, lo que no tiene sentido ... más tiempo para resolverlo ... gracias por la sugerencia de geterrorstream. – Brenden

+1

Funciona. Compruebe el código de respuesta y luego getErrorStream() o getInputStream() de manera correspondiente. El fragmento de código debe proporcionarse en este caso. – Emerald214

+0

comprobando el código de respuesta me ayudó mucho. ahora no estoy encontrando FileNotFoundException .. gracias @bcody –

2

Sé que esto es un hilo viejo, pero he encontrado una solución no aparece en cualquier lugar aquí.

Estaba tratando de extraer datos en formato json de un servlet J2EE en el puerto 8080, pero estaba recibiendo el error de archivo no encontrado. Pude extraer estos mismos datos json de un servidor php que se ejecuta en el puerto 80.

Resulta que en el servlet, necesitaba cambiar doGet a doPost.

Espero que esto ayude a alguien.

0

se han topado con un problema similar, pero la razón parece ser diferente, aquí es la traza excepción:

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 

por lo que parece que acaba de conseguir el código de respuesta hará que la conexión URL para callGetInputStream.

+2

Solucioné el problema lanzando HttpUrlConnection y utilizando Apache HttpClient en su lugar. Mucho mejor rendimiento y un código mucho más limpio. –

0

Sé que esto es un hilo viejo, pero acabo de notar algo sobre esto, así que pensé en ponerlo allí.

Como mencionó Jessica, esta excepción se produce cuando se utiliza un puerto no estándar.

Parece que solo sucede cuando se usa DNS. Si utilizo el número de IP, puedo especificar el número de puerto y todo funciona bien.

Cuestiones relacionadas