web-dev-qa-db-fra.com

Impossible d'écrire la sortie après avoir lu l'entrée

J'écris un programme qui se connecte à une servlet grâce à un HttpURLConnection mais je suis resté bloqué lors de la vérification de l'URL

public void connect (String method) throws Exception {

server = (HttpURLConnection) url.openConnection ();
server.setDoInput (true);
server.setDoOutput (true);
server.setUseCaches (false);
server.setRequestMethod (method);
server.setRequestProperty ("Content-Type", "application / xml");

server.connect ();

/*if (server.getResponseCode () == 200)
{
System.out.println ("Connection OK at the url:" + url);
System.out.println ("------------------------------------------- ------- ");
}
else
System.out.println ("Connection failed"); 

}*/

J'ai eu l'erreur: 

Java.net.ProtocolException: impossible d'écrire la sortie après la lecture de l'entrée.

si je vérifie l’URL avec le code dans les commentaires mais qu’il fonctionne parfaitement sans elle malheureusement, j’ai besoin de vérifier l’URL, donc je pense que le problème vient de la méthode getResponseCode mais je ne sais pas comment le résoudre.

Merci beaucoup

13
ulquiorra

Le protocole HTTP est basé sur un modèle de requête-réponse: vous envoyez d'abord votre requête et le serveur répond. Une fois que le serveur a répondu, vous ne pouvez plus envoyer de contenu, cela n’a aucun sens. (Comment le serveur peut-il vous donner un code de réponse avant il sait ce que vous essayez d'envoyer?)

Ainsi, lorsque vous appelez server.getResponseCode(), vous informez effectivement le serveur que votre demande est terminée et qu'il peut la traiter. Si vous souhaitez envoyer plus de données, vous devez commencer une nouvelle demande.

En regardant votre code, vous voulez vérifier si la connexion elle-même a réussi, mais ce n'est pas nécessaire: si la connexion échoue, une Exception est lancée par server.connect(). Mais le résultat d'une tentative de connexion n'est pas le même que le code de réponse HTTP, qui survient toujours après que le serveur a traité toutes vos entrées.

24
biziclop

Je pense que l'exception n'est pas due àprinting url. Il devrait y avoir un morceau de code qui tente d’écrire pour définir le corps de la demande après la lecture de la réponse. 

Cette exception se produira si vous essayez d’obtenir HttpURLConnection.getOutputStream() après avoir obtenu HttpURLConnection.getInputStream().

Voici l'implémentation de Sun.net.www.protocol.http.HttpURLConnection.getOutputStream:

public synchronized OutputStream getOutputStream() throws IOException {

     try {
         if (!doOutput) {
             throw new ProtocolException("cannot write to a URLConnection"
                            + " if doOutput=false - call setDoOutput(true)");
         }

         if (method.equals("GET")) {
             method = "POST"; // Backward compatibility
         }
         if (!"POST".equals(method) && !"PUT".equals(method) &&
             "http".equals(url.getProtocol())) {
             throw new ProtocolException("HTTP method " + method +
                                         " doesn't support output");
         }

         // if there's already an input stream open, throw an exception
         if (inputStream != null) {
             throw new ProtocolException("Cannot write output after reading 
                input.");
         }

         if (!checkReuseConnection())
             connect();

         /* REMIND: This exists to fix the HttpsURLConnection subclass.
          * Hotjava needs to run on JDK.FCS.  Do proper fix in subclass
          * for . and remove this.
          */

         if (streaming() && strOutputStream == null) {
             writeRequests();
         }
         ps = (PrintStream)http.getOutputStream();
         if (streaming()) {
             if (strOutputStream == null) {
                 if (fixedContentLength != -) {
                     strOutputStream = 
                        new StreamingOutputStream (ps, fixedContentLength);
                 } else if (chunkLength != -) {
                     strOutputStream = new StreamingOutputStream(
                         new ChunkedOutputStream (ps, chunkLength), -);
                 }
             }
             return strOutputStream;
         } else {
             if (poster == null) {
                 poster = new PosterOutputStream();
             }
             return poster;
         }
     } catch (RuntimeException e) {
         disconnectInternal();
         throw e;
     } catch (IOException e) {
         disconnectInternal();
         throw e;
     }
 }
7
Ramesh PVK

J'ai eu le même problème. La solution au problème est que vous devez utiliser la séquence

openConnection -> getOutputStream -> write -> getInputStream -> read

Cela signifie..:

public String sendReceive(String url, String toSend) {
URL url = new URL(url);
URLConnection conn = url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.sets...

OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(toSend);
out.close();

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String receive = "";
do {
    String line = in.readLine();
    if (line == null)
        break;
    receive += line;
} while (true);
in.close();

return receive;
}

String results1 = sendReceive("site.com/update.php", params1);
String results2 = sendReceive("site.com/update.php", params2);
...
1
SauloAlessandre

J'ai ce problème aussi, ce qui me surprend, c'est que l'erreur est causée par mon code ajouté System.out.println(conn.getHeaderFields());

Ci-dessous mon code:

HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
configureConnection(conn);
//System.out.println(conn.getHeaderFields()); //if i comment this code,everything is ok, if not the 'Cannot write output after reading input' error happens
conn.connect();
OutputStream os = conn.getOutputStream();
os.write(paramsContent.getBytes());
os.flush();
os.close();
1
chou