# 读取和写入 URLConnection

> 原文： [https://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html](https://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html)

`URLConnection`类包含许多方法，可让您通过网络与 URL 进行通信。 `URLConnection`是一个以 HTTP 为中心的类;也就是说，只有在使用 HTTP URL 时，它的许多方法才有用。但是，大多数 URL 协议允许您读取和写入连接。本节介绍这两种功能。

## 从 URLConnection 读取

以下程序执行与[直接从 URL](readingURL.html) 读取中显示的`URLReader`程序相同的功能。

但是，该程序不是直接从 URL 获取输入流，而是显式检索`URLConnection`对象并从连接获取输入流。通过调用`getInputStream`隐式打开连接。然后，像`URLReader`一样，该程序在输入流上创建一个`BufferedReader`并从中读取。粗体语句突出显示了此示例与上一个示例之间的差异：

```
import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL oracle = new URL("http://www.oracle.com/");
        URLConnection yc = oracle.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(
                                    yc.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);
        in.close();
    }
}

```

此程序的输出与直接从 URL 打开流的程序的输出相同。您可以使用任一方式从 URL 读取。但是，从`URLConnection`读取而不是直接从 URL 读取可能更有用。这是因为您可以同时将`URLConnection`对象用于其他任务（例如写入 URL）。

同样，如果程序挂起或您看到错误消息，则可能必须设置代理主机以便程序可以找到 Oracle 服务器。

## 写入 URLConnection

许多 HTML 页面包含 _ 表单 _ - 文本字段和其他 GUI 对象，可让您输入要发送到服务器的数据。键入所需信息并通过单击按钮启动查询后，Web 浏览器会通过网络将数据写入 URL。在另一端，服务器接收数据，处理数据，然后通常以新的 HTML 页面的形式向您发送响应。

许多这些 HTML 表单使用 HTTP POST METHOD 将数据发送到服务器。因此，写入 URL 通常称为 _ 发布到 URL_ 。服务器识别 POST 请求并读取从客户端发送的数据。

对于 Java 程序与服务器端进程交互，它必须能够写入 URL，从而向服务器提供数据。它可以通过以下步骤完成此操作：

1.  创建`URL`。
2.  检索`URLConnection`对象。
3.  在`URLConnection`上设置输出功能。
4.  打开与资源的连接。
5.  从连接获取输出流。
6.  写入输出流。
7.  关闭输出流。

这是一个名为

在容器中运行的 servlet 从其 InputStream 读取，反转该字符串，并将其写入其 OutputStream。 servlet 需要输入`string=string_to_reverse`形式，其中`string_to_reverse`是要以相反顺序显示其字符的字符串。

这是一个通过`URLConnection`在网络上运行`ReverseServlet`的示例程序：

```
import java.io.*;
import java.net.*;

public class Reverse {
    public static void main(String[] args) throws Exception {

        if (args.length != 2) {
            System.err.println("Usage:  java Reverse "
                + "http://<location of your servlet/script>"
                + " string_to_reverse");
            System.exit(1);
        }

        String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

        URL url = new URL(args[0]);
        URLConnection connection = url.openConnection();
        connection.setDoOutput(true);

        OutputStreamWriter out = new OutputStreamWriter(
                                         connection.getOutputStream());
        out.write("string=" + stringToReverse);
        out.close();

        BufferedReader in = new BufferedReader(
                                    new InputStreamReader(
                                    connection.getInputStream()));
        String decodedString;
        while ((decodedString = in.readLine()) != null) {
            System.out.println(decodedString);
        }
        in.close();
    }
}

```

让我们检查一下程序，看看它是如何工作的。首先，程序处理其命令行参数：

```
if (args.length != 2) {
    System.err.println("Usage:  java Reverse "
        + "http://<location of your servlet/script>"
        + " string_to_reverse");
    System.exit(1);
}       

String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

```

这些语句确保用户为程序提供两个且仅两个命令行参数。命令行参数是`ReverseServlet`的位置和将被反转的字符串。它可能包含空格或其他非字母数字字符。必须对这些字符进行编码，因为字符串在到服务器的途中被处理。 `URLEncoder`类方法对字符进行编码。

接下来，程序创建`URL`对象，并设置连接以便它可以写入：

```
URL url = new URL(args[0]);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);

```

然后程序在连接上创建输出流并在其上打开`OutputStreamWriter`：

```
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());

```

如果 URL 不支持输出，`getOutputStream`方法将抛出`UnknownServiceException`。如果 URL 支持输出，则此方法返回连接到服务器端 URL 的输入流的输出流 - 客户端的输出是服务器的输入。

接下来，程序将所需信息写入输出流并关闭流：

```
out.write("string=" + stringToReverse);
out.close();

```

此代码使用`write`方法写入输出流。因此，您可以看到将数据写入 URL 就像将数据写入流一样简单。写入客户端输出流的数据是服务器端 servlet 的输入。 `Reverse`程序通过将`string=`前置到要反转的编码字符串，以脚本所需的格式构造输入。

servlet 读取您编写的信息，对字符串值执行反向操作，然后将其发送给您。您现在需要读取服务器已发回的字符串。 `Reverse`程序是这样的：

```
BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                            connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
    System.out.println(decodedString);
}
in.close();

```

如果`ReverseServlet`位于`http://example.com/servlet/ReverseServlet`，则使用时运行`Reverse`程序

```
http://example.com/servlet/ReverseServlet "Reverse Me"

```

作为参数（包括双引号），你应该看到这个输出：

```
Reverse Me
 reversed is: 
eM esreveR

```