web-dev-qa-db-fra.com

FileNotFoundException lors de l'obtention de l'objet InputStream à partir de HttpURLConnection

J'essaie d'envoyer une demande de publication à une URL à l'aide de HttpURLConnection (pour utiliser cUrl en Java). Le contenu de la demande est xml et, à la fin, l'application traite le xml et stocke un enregistrement dans la base de données, puis renvoie une réponse sous la forme d'une chaîne xml. L'application est hébergée localement sur Apache-Tomcat.

Lorsque j'exécute ce code à partir du terminal, une ligne est ajoutée à la base de données comme prévu. Mais une exception est levée comme suit lors de l’obtention du InputStream de la connexion

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)

Voici le 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();
        }
    }
  }

C'est déroutant parce que l'exception est reliée à la ligne InputStream response = con.getInputStream(); et qu'il ne semble y avoir aucun fichier impliqué pour une exception FileNotFoundException.

Lorsque j'essaie d'ouvrir directement une connexion à un fichier XML, il ne lève pas cette exception.

L'application de service utilise Spring Framework et Jaxb2Marshaller pour créer la réponse xml.

La classe ReadWriteTextFile est tirée de ici

Merci.

Edit: Eh bien, il enregistre les données dans la base de données et renvoie un code d'état de la réponse 404 en même temps.

J'ai également essayé de faire une boucle en utilisant php et imprimer le CURLINFO_HTTP_CODE Qui se révèle être 200.

Des idées sur la façon de procéder pour déboguer cela? Le service et le client sont sur le serveur local.

résolu: Je pourrais résoudre le problème après avoir fait référence à un réponse sur SO lui-même.

Il semble que HttpURLConnection renvoie toujours la réponse 404 lors de la connexion à une URL avec un port non standard.

L'ajout de ces lignes l'a résolu

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

Je ne connais pas votre combinaison Spring/JAXB, mais la moyenne REST webservice ne renvoie pas de corps de réponse sous POST/PUT, mais juste un statut de la réponse . Vous aimeriez le déterminer à la place du corps.

Remplacer

InputStream response = con.getInputStream();

par

int status = con.getResponseCode();

Tous les codes d'état disponibles et leur signification sont disponibles dans la spécification HTTP, comme précédemment lié. Le service Web lui-même devrait également être accompagné d'une documentation qui passe en revue tous les codes d'état pris en charge par le service Web et leur signification particulière, le cas échéant.

Si le statut commence par 4nn Ou 5nn, Vous voudriez utiliser getErrorStream() à la place pour lire le corps de la réponse pouvant contenir les détails de l'erreur.

InputStream error = con.getErrorStream();
122
BalusC

FileNotFound est simplement une exception malheureuse utilisée pour indiquer que le serveur Web a renvoyé un 404.

47
Jon Skeet

La raison en est que le code d'état était un 404 (ou dans mon cas, un 500). Il semble que la fonction InpuStream renvoie une erreur lorsque le code d'état n'est pas 200.

Dans mon cas, je contrôle mon propre serveur et renvoyais un code d'état 500 pour indiquer qu'une erreur s'était produite. Malgré le fait que j'envoie aussi un corps avec un message de chaîne détaillant l'erreur, le inputstream a lancé une erreur, que le corps soit complètement lisible.

Si vous contrôlez votre serveur, je suppose que cela peut être géré en vous envoyant un code de statut 200, puis en gérant la réponse d'erreur de chaîne.

28
Terence Chow

Pour ceux qui sont tombés dessus, la même chose m'est arrivé en essayant d'envoyer un en-tête de requête SOAP à un service SOAP. Le problème était un ordre erroné dans En ce qui concerne le code, j'ai d'abord demandé le flux d'entrée avant d'envoyer le corps XML Dans le code extrait ci-dessous, la ligne InputStream in = conn.getInputStream(); est venue juste après ByteArrayOutputStream out = new ByteArrayOutputStream();, ce qui correspond à un ordre incorrect.

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 dans ce cas était un moyen malheureux d’encoder le code de réponse HTTP 400.

5
zero0cool

FileNotFound dans ce cas signifie que vous avez reçu un 404 de votre serveur - est-ce que le serveur n'aime pas les requêtes "POST"?

4
tofarr

La solution:
changez simplement localhost pour le IP de votre PC
si vous voulez savoir ceci: Windows + r> cmd> ipconfig
exemple: http: // 192.168.0.107/répertoire/service/programme.php? action = sendQuelque chose
remplacez simplement 192.168.0.107 pour votre propre adresse IP (n'essayez pas 127.0.0.1 car c'est la même chose que localhost)

0
charlie