此Java教程适用于JDK 8。本页面中描述的示例和实践未利用后续版本中引入的改进,并可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言功能的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
URLConnection
类包含许多方法,让您可以通过网络与URL进行通信。URLConnection
是一个以HTTP为中心的类;也就是说,在处理HTTP URL时,它的许多方法才有用。然而,大多数URL协议允许您从连接中读取和写入数据。本节将介绍这两种功能。
下面的程序执行的功能与直接从URL中读取数据中展示的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读取数据。但是,与直接从URL读取数据相比,从URLConnection
读取数据可能更有用。因为您可以同时将URLConnection
对象用于其他任务(比如向URL写入数据)。
同样,如果程序卡住或者出现错误消息,您可能需要设置代理主机,以便程序可以找到Oracle服务器。
许多HTML页面包含表单 - 文本字段和其他GUI对象,让您输入要发送到服务器的数据。在您输入所需信息并通过单击按钮发起查询后,您的Web浏览器通过网络将数据写入URL。在另一端,服务器接收到数据,进行处理,然后向您发送响应,通常是一个新的HTML页面。
许多这些HTML表单使用HTTP POST METHOD将数据发送到服务器。因此,写入URL通常被称为“向URL发送POST请求”。服务器识别POST请求并读取从客户端发送的数据。
要使Java程序与服务器端的进程进行交互,它只需要能够向URL写入数据,从而向服务器提供数据。它可以按照以下步骤完成:
URL
对象。URLConnection
对象。URLConnection
的输出功能。这里有一个小的名为 ReverseServlet
(或者如果你更喜欢cgi-bin脚本)。你可以使用这个servlet来测试以下示例程序。
在容器中运行的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://<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://<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