web-dev-qa-db-fra.com

URLConnection FileNotFoundException pour les sources de port HTTP non standard

J'essayais d'utiliser la tâche Apache Ant Get pour obtenir une liste des WSDL générés par une autre équipe de notre société. Ils les ont hébergés sur un serveur weblogic 9.x sur http: //....com: 7925/services/ . Je peux accéder à la page via un navigateur, mais la tâche d’obtention me donne une exception FileNotFoundException lorsque je tente de copier la page dans un fichier local à analyser. J'étais toujours capable d'obtenir (à l'aide de la tâche ant) ​​une URL sans le port non standard 80 pour HTTP. 

J'ai parcouru le code source Ant et ai réduit l'erreur à la connexion URLConnection. Il semble que l'URLConnection ne reconnaisse pas que les données constituent du trafic HTTP, car elles ne sont pas sur le port standard, même si le protocole est défini sur HTTP. J'ai détecté le trafic à l'aide de WireShark et la page se charge correctement sur le réseau, mais obtient toujours la FileNotFoundException. 

Voici un exemple où vous verrez l'erreur (avec l'URL modifiée pour protéger l'innocent). L'erreur est renvoyée sur 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());
        }
    }

}
23
jeffl8n

vérifier le code de réponse renvoyé par le serveur

7
objects

La réponse à ma demande HTTP a été renvoyée avec un code d'état 404, ce qui a entraîné une exception FileNotFoundException lorsque j'ai appelé getInputStream (). Je voulais toujours lire le corps de la réponse et je devais donc utiliser une méthode différente: HttpURLConnection # getErrorStream () .

Voici un extrait JavaDoc de getErrorStream ():

Renvoie le flux d'erreur si le La connexion a échoué mais le serveur a envoyé données utiles néanmoins. Le typique Par exemple, un serveur HTTP répond avec un 404, ce qui provoquera une exception FileNotFoundException à lever en connexion, mais le serveur a envoyé un Page d’aide HTML avec des suggestions quant à Que faire.

Exemple d'utilisation:

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();
        }
    }
}
46
bcody

C'est un vieux fil, mais j'ai eu un problème similaire et j'ai trouvé une solution qui n'est pas listée ici. 

Je recevais bien la page dans le navigateur, mais j'ai obtenu un 404 lorsque j'ai essayé d'y accéder via la connexion HttpURLC. L'URL que j'essayais d'accéder contenait un numéro de port. Lorsque j'ai essayé sans le numéro de port, j'ai réussi à obtenir une page fictive via HttpURLConnection. Il semblait donc que le problème était le port non standard.

J'ai commencé à penser que l'accès était restreint et, en un sens, c'était le cas. Ma solution a été que je devais dire au serveur l'agent utilisateur et je spécifiais également les types de fichiers que j'attendais. J'essaie de lire un fichier .json, j'ai donc pensé que le type de fichier pouvait également être une spécification nécessaire.

J'ai ajouté ces lignes et cela a finalement fonctionné:

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

Je sais que c'est un vieux fil, mais j'ai trouvé une solution qui ne figure nulle part ici.

J'essayais d'extraire des données au format JSON d'un servlet J2EE sur le port 8080 mais je recevais le fichier introuvable. J'ai pu extraire ces mêmes données JSON d'un serveur PHP fonctionnant sur le port 80.

Il s'est avéré que dans la servlet, je devais changer doPet to doPost.

J'espère que ça aide quelqu'un.

2
NullPointer

Je sais que c'est un vieux fil, mais je viens de remarquer quelque chose sur celui-ci, alors j'ai pensé le mettre en avant.

Comme Jessica l'a mentionné, cette exception est levée lors de l'utilisation d'un port non standard.

Cela ne semble se produire que lorsque vous utilisez DNS. Si j'utilise un numéro IP, je peux spécifier le numéro de port et tout fonctionne correctement.

0
Zyga

J'ai essayé cela localement - en utilisant le code fourni - et je ne reçois pas de FileNotFoundException sauf lorsque le serveur renvoie une réponse d'état 404.

Êtes-vous sûr de vous connecter au serveur Web auquel vous souhaitez vous connecter? Avez-vous une chance de vous connecter à un autre serveur Web? (Je remarque que le numéro de port dans le code ne correspond pas au numéro de port dans le lien)

0
Daniel Martin

J'ai rencontré un problème similaire mais la raison semble être différente, voici la trace d'exception:

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

Il semblerait donc que le simple fait d'obtenir le code de réponse entraîne la connexion de l'URL à callGetInputStream.

0
Steve Owens

Vous pouvez utiliser OkHttp :

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}
0
serv-inc