你为什么要调用URLConnection#getInputStream才能写出URLConnection#getOutputStream? [英] Why do you have to call URLConnection#getInputStream to be able to write out to URLConnection#getOutputStream?

查看:145
本文介绍了你为什么要调用URLConnection#getInputStream才能写出URLConnection#getOutputStream?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试写出 URLConnection#getOutputStream 但是,在我调用 URLConnection#getInputStream 。即使我设置了 URLConnnection#doInput 为false,它仍然不会发送。有人知道为什么吗? API文档中没有任何内容描述这一点。

I'm trying to write out to URLConnection#getOutputStream, however, no data is actually sent until I call URLConnection#getInputStream. Even if I set URLConnnection#doInput to false, it still will not send. Does anyone know why this is? There's nothing in the API documentation that describes this.

URLConnection上的Java API文档: http://download.oracle.com/javase/6/docs/api/java/net/URLConnection.html

Java API Documentation on URLConnection: http://download.oracle.com/javase/6/docs/api/java/net/URLConnection.html

Java的读取和写入URLConnection的教程: http://download.oracle.com/javase/tutorial/networking/urls/readingWriting.html

Java's Tutorial on Reading from and Writing to a URLConnection: http://download.oracle.com/javase/tutorial/networking/urls/readingWriting.html

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;

public class UrlConnectionTest {

    private static final String TEST_URL = "http://localhost:3000/test/hitme";

    public static void main(String[] args) throws IOException  {

        URLConnection urlCon = null;
        URL url = null;
        OutputStreamWriter osw = null;

        try {
            url = new URL(TEST_URL);
            urlCon = url.openConnection();
            urlCon.setDoOutput(true);
            urlCon.setRequestProperty("Content-Type", "text/plain");            

            ////////////////////////////////////////
            // SETTING THIS TO FALSE DOES NOTHING //
            ////////////////////////////////////////
            // urlCon.setDoInput(false);

            osw = new OutputStreamWriter(urlCon.getOutputStream());
            osw.write("HELLO WORLD");
            osw.flush();

            /////////////////////////////////////////////////
            // MUST CALL THIS OTHERWISE WILL NOT WRITE OUT //
            /////////////////////////////////////////////////
            urlCon.getInputStream();

            /////////////////////////////////////////////////////////////////////////////////////////////////////////
            // If getInputStream is called while doInput=false, the following exception is thrown:                 //
            // java.net.ProtocolException: Cannot read from URLConnection if doInput=false (call setDoInput(true)) //
            /////////////////////////////////////////////////////////////////////////////////////////////////////////

        } catch (Exception e) {
            e.printStackTrace();                
        } finally {
            if (osw != null) {
                osw.close();
            }
        }

    }

}


推荐答案

URLConnection和HttpURLConnection的API(无论好坏)都是为用户设计的,以便遵循非常具体的事件序列:

The API for URLConnection and HttpURLConnection are (for better or worse) designed for the user to follow a very specific sequence of events:


  1. 设置请求属性

  2. (可选)getOutputStream(),写入流,关闭流

  3. getInputStream(),从流中读取,关闭流

如果您的请求是POST或PUT,需要可选的步骤#2。

If your request is a POST or PUT, you need the optional step #2.

据我所知,OutputStream不像套接字,它不直接连接到服务器上的InputStream。相反,在关闭或刷新流之后,AND调用getInputStream(),您的输出将内置到Request中并发送。语义基于您希望读取响应的假设。我见过的每个例子都显示了这种事件的顺序。我肯定会同意你和其他人的说法,与普通的流I / O API相比,这个API是违反直觉的。

To the best of my knowledge, the OutputStream is not like a socket, it is not directly connected to an InputStream on the server. Instead, after you close or flush the stream, AND call getInputStream(), your output is built into a Request and sent. The semantics are based on the assumption that you will want to read the response. Every example that I've seen shows this order of events. I would certainly agree with you and others that this API is counterintuitive when compared to the normal stream I/O API.

教程链接到URLConnection是一个以HTTP为中心的类的状态。我认为这意味着方法是围绕Request-Response模型设计的,并假设它们将如何使用。

The tutorial you link to states that "URLConnection is an HTTP-centric class". I interpret that to mean that the methods are designed around a Request-Response model, and make the assumption that is how they will be used.

为了它的价值,我发现这个错误报告解释了该课程的预期操作比javadoc文档。对报告的评估指出发出请求的唯一方法是调用getInputStream。

For what it's worth, I found this bug report that explains the intended operation of the class better than the javadoc documentation. The evaluation of the report states "The only way to send out the request is by calling getInputStream."

这篇关于你为什么要调用URLConnection#getInputStream才能写出URLConnection#getOutputStream?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆