String message = URLEncoder.encode("my message", "UTF-8");
try {
URL url = new URL("http://www.example.com/comment");
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write("message=" + message);
writer.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
} else {
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
在上面的HTTP POST示例中,前三个回答列为内联注释,位于每个方法旁边。从
getOutputStream开始:
返回一个写入此连接的输出流。
基本上,我认为您已经很好地理解了它的工作原理,所以让我用通俗易懂的话再重申一遍。
getOutputStream
基本上打开一个流,目的是将数据写入服务器。在上面的代码示例中,“message”可以是我们发送到服务器的评论,表示对帖子的评论。当您看到
getOutputStream
时,您正在打开用于写入的流,但是直到调用
writer.write("message=" + message);
之后才实际写入任何数据。
从
getInputStream()开始:
返回一个从此开放连接读取的输入流。如果在数据可供读取之前读取超时到期,则可能抛出SocketTimeoutException。
getInputStream则相反。与getOutputStream一样,它也打开了一个流,但意图是从服务器读取数据,而不是写入数据。如果连接或流打开失败,您将看到SocketTimeoutException。
getInputStream怎么样?由于我只能在getInputStream中获取响应,那么这是否意味着我尚未在getOutputStream中发送任何请求,而只是建立了连接?
请记住,发送请求和发送数据是两个不同的操作。当您调用url.openConnection()时,您向服务器发送请求以建立连接。发生握手,服务器向您发送确认,表示连接已建立。然后就在这个时间点上,您准备好发送或接收数据。因此,除非您的目的是发送数据,否则不需要调用getOutputStream来打开流。
通俗易懂地讲,使用 getInputStream
请求相当于打电话给你的朋友家,询问“嘿,我可以过来借那把卡簧钳吗?” 你的朋友通过回答“当然可以!过来拿吧”建立了握手。此时连接已经建立,你走到朋友家,敲门,请求卡簧钳,然后走回自己家。
类似地,使用 getOutputStream
的例子就是你打电话给你的朋友说“嘿,我欠你的钱我有了,我能把它寄给你吗?” 你的朋友需要这笔钱,但内心深感你将钱保留了这么长时间,于是说“当然,便宜鬼,快过来吧”。所以你走到朋友家,向他“POST”了钱,然后被赶出去,走回自己家。
现在,继续使用通俗易懂的例子,让我们看一些异常情况。如果你打电话给朋友,他不在家,那可能是一个500错误。如果你拨打的号码无法接通,因为你的朋友厌倦了你总是借钱,那就是404页面未找到。如果你的手机因为没有支付账单而无法使用,那可能是一个IOException。(注意:这部分内容可能不完全正确。它旨在用通俗易懂的方式给你一个大致的了解。)
问题 #5:
是的,你是正确的,openConnection只是创建了一个新的连接对象,但并没有建立连接。当你调用getInputStream或getOutputStream时,连接才会建立。
openConnection
创建了一个新的连接对象。从URL.openConnection javadocs中可以看到:
每次通过调用此URL的协议处理程序的openConnection方法来打开一个新的连接。
当你调用openConnection时,连接会建立,并且当你实例化InputStream、OutputStream或两者时,它们也会被调用。
第六个问题:
为了测量开销,我通常会在整个连接块周围包装一些非常简单的计时代码,如下所示:
long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );
我相信有更高级的方法来测量请求时间和开销,但对于我的需求来说,这通常已经足够了。
关于关闭连接的信息,您没有提问,请参见
在Java中何时关闭URL连接?。
connection.setDoOutput(true);
意味着POST
。同时,你必须更正你的示例代码,使用openConnection()
是一个 NOOP(无操作),直到实际需要连接时才会抛出异常 - 参见下面的链接:openConnection
仅创建一个新的连接对象,但并不建立任何连接。至少在 Android 中,也就是 Java 6 中,除非尝试创建流、获取响应代码等,否则不会抛出任何异常。 - Mr_and_Mrs_DopenConnection
似乎并没有做太多事情。尝试使用openConnection(“不存在的URL”); sleep; disconnect;
- 会发生什么?(不确定,但我猜测不会有任何异常等) - Mr_and_Mrs_D