URLConnection FileNotFoundException pour les sources de port HTTP non standard
J'essayais d'utiliser la fourmi Apache Get
task pour obtenir une liste de WSDLs générés par une autre équipe de notre société. Ils les ont hébergés sur un weblogic 9.serveur X sur http://....com:7925/services/. je suis capable d'accéder à la page via un navigateur, mais la tâche get me donne une exception FileNotFoundException lorsque vous essayez de copier la page dans un fichier local à analyser. J'étais toujours capable d'obtenir (en utilisant la tâche ant) une URL sans le port non standard 80 pour HTTP.
J'ai regardé à travers le code source Ant, et réduit l'erreur à L'URLConnection. Il semble que L'URLConnection ne reconnaisse pas que les données sont du trafic HTTP, car elles ne sont pas sur le port standard, même si le protocole est spécifié en tant que HTTP. J'ai reniflé le trafic en utilisant WireShark et la page se charge correctement sur le fil, mais obtient toujours L'exception FileNotFoundException.
Voici un exemple où vous verrez l'erreur (avec L'URL modifiée pour protéger les innocents). L'erreur est lancé sur connexion.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());
}
}
}
8 réponses
La réponse à ma requête HTTP est retournée avec un code d'état 404, ce qui a donné lieu à une exception FileNotFoundException lorsque j'ai appelé getInputStream(). Je voulais toujours lire le corps de la réponse, donc j'ai dû utiliser une méthode différente: HttpURLConnection#getErrorStream () .
Voici un extrait JavaDoc de getErrorStream ():
Renvoie le flux d'erreur si la connexion a échoué mais le serveur a envoyé données utiles néanmoins. Le typique exemple est quand un serveur HTTP répond avec un 404, ce qui provoquera une exception FileNotFoundException à lancer dans connexion, mais le serveur a envoyé une Page D'aide HTML avec des suggestions quant à de quoi 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();
}
}
}
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 eu un 404 quand j'ai essayé d'y accéder via HttpURLConnection. L'URL à laquelle j'essayais d'accéder contenait un numéro de port. Quand je l'ai essayé sans le numéro de port, j'ai réussi à obtenir une page factice via HttpURLConnection. Il semblait donc que le port non standard était le problème.
J'ai commencé à penser que l'accès était restreint, et dans un sens il était. Ma solution était que je devais dire au serveur L'agent utilisateur et je spécifie également les types de fichiers que j'attends. Je suis en train de lire un .fichier json, donc j'ai pensé que le type de fichier pourrait é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","*/*");
Je sais que c'est un vieux fil mais j'ai trouvé une solution qui n'est répertoriée nulle part ici.
J'essayais d'extraire des données au format json à partir d'un servlet J2EE sur le port 8080 mais je recevais l'erreur file not found. J'ai pu extraire ces mêmes données json à partir d'un serveur php fonctionnant sur le port 80.
Il s'avère que dans le servlet, j'avais besoin de changer doGet en doPost.
J'espère que cela aide quelqu'un.
J'ai essayé cela localement-en utilisant le code fourni - et je n'obtiens pas de FileNotFoundException
sauf lorsque le serveur renvoie une réponse status 404.
Êtes-vous sûr de vous connecter au serveur web auquel vous avez l'intention de vous connecter? Est-il possible que vous êtes connecté à un autre serveur? (Je note que le numéro de port dans le code ne correspond pas au numéro de port dans le lien)
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înera la connexion URL à callGetInputStream.
Je sais que c'est un vieux fil mais j'ai juste remarqué quelque chose sur celui-ci alors j'ai pensé que je vais juste le mettre là-bas.
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 le numéro IP je peux spécifier le numéro de port et tout fonctionne bien.
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(); }