JAVA网络编程之获取网络资源

在应用程序开发过程中,很多时候我们会用网络资源,比如接口调用等。Java中也提供了相关的类去处理网络资源,而我们在处理网络资源的时候,用到的最多的就是IO,所以对IO还不了解的可以先看看前面的博客。
Java中,处理网络资源、网络通信所需要的类都在java.net包中。

URL

类URL代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。通过URL,我们可以定位网络资源。

构造方法

方法名 说明
URL(String spec) 根据 String 表示形式创建 URL 对象
URL(String protocol, String host, int port, String file) 根据指定 protocol、host、port 号和 file 创建 URL 对象
URL(String protocol, String host, int port, String file, URLStreamHandler handler) 根据指定的 protocol、host、port 号、file 和 handler 创建 URL 对象
URL(String protocol, String host, String file) 根据指定的 protocol 名称、host 名称和 file 名称创建 URL
URL(URL context, String spec) 通过在指定的上下文中对给定的 spec 进行解析创建 URL
URL(URL context, String spec, URLStreamHandler handler) 通过在指定的上下文中用指定的处理程序对给定的 spec 进行解析来创建 URL

方法摘要

返回值 方法名 说明
int getDefaultPort() 获取与此 URL 关联协议的默认端口号
String getFile() 获取此 URL 的文件名
String getHost() 获取此 URL 的主机名(如果适用)
String getPath() 获取此 URL 的路径部分
int getPort() 获取此 URL 的端口号
String getProtocol() 获取此 URL 的协议名称
String getQuery() 获取此 URL 的查询部分
String getRef() 获取此 URL 的锚点(也称为“引用”)
String getUserInfo() 获取此 URL 的 userInfo 部分
URLConnection openConnection() 返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接
URLConnection openConnection(Proxy proxy) 与 openConnection()类似,所不同是连接通过指定的代理建立;不支持代理方式的协议处理程序将忽略该代理参数并建立正常的连接
InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream
static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) 设置应用程序的 URLStreamHandlerFactory
String toExternalForm() 构造此 URL 的字符串表示形式
String toString() 构造此 URL 的字符串表示形式
URI toURI() 返回与此 URL 等效的 URI

使用示例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class URLDemo
{
   public static void main(String[] args)
   {
      try
      {
         // 以百度为例
         URL url = new URL("http://www.baidu.com");
         // 内容是文本,直接以缓冲字符流读取
         BufferedReader reader = new BufferedReader(new InputStreamReader(
               url.openStream(), "UTF-8"));
         String data = null;
         while ((data = reader.readLine()) != null)
         {
            System.out.print(data);
         }
         reader.close();
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
   }
}

URLConnection

抽象类URLConnection是所有类的超类,它代表应用程序和URL之间的通信链接。此类的实例可用于读取和写入此URL引用的资源。通常,创建一个到 URL的连接需要几个步骤:

  1. 通过在 URL 上调用 openConnection 方法创建连接对象。
  2. 处理设置参数和一般请求属性。
  3. 使用 connect 方法建立到远程对象的实际连接。
  4. 远程对象变为可用。远程对象的头字段和内容变为可访问

使用以下方法修改设置参数:

  • setAllowUserInteraction
  • setDoInput
  • setDoOutput
  • setIfModifiedSince
  • setUseCaches

使用以下方法修改一般请求属性:

  • setRequestProperty

使用 setDefaultAllowUserInteraction 和 setDefaultUseCaches 可设置 AllowUserInteraction 和 UseCaches 参数的默认值。

上面每个 set 方法都有一个用于获取参数值或一般请求属性值的对应 get 方法。适用的具体参数和一般请求属性取决于协议。

在建立到远程对象的连接后,以下方法用于访问头字段和内容:

  • getContent
  • getHeaderField
  • getInputStream
  • getOutputStream

某些头字段需要经常访问。以下方法:

  • getContentEncoding
  • getContentLength
  • getContentType
  • getDate
  • getExpiration
  • getLastModifed

提供对这些字段的便捷访问。getContent 方法使用 getContentType 方法以确定远程对象类型;子类重写 getContentType 方法很容易。

一般情况下,所有的预连接参数和一般请求属性都可忽略:预连接参数和一般请求属性默认为敏感值。对于此接口的大多数客户端而言,只有两个需要的方法:getInputStream 和 getContent,它们通过便捷方法镜像到 URL 类中。

方法摘要

返回值 方法名 说明
void addRequestProperty(String key, String value) 添加由键值对指定的一般请求属性
abstract void connect() 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)
boolean getAllowUserInteraction() 返回此对象的allowUserInteraction字段的值
int getConnectTimeout() 返回连接超时设置
Object getContent() 获取此 URL 连接的内容
Object getContent(Class[] classes) 获取此 URL 连接的内容
String getContentEncoding() 返回 content-encoding 头字段的值
int getContentLength() 返回 content-length 头字段的值
String getContentType() 返回 content-type 头字段的值
long getDate() 返回 date 头字段的值
boolean getDefaultUseCaches() 返回 URLConnection 的 useCaches 标志的默认值
boolean getDoInput() 返回此 URLConnection 的 doInput 标志的值
boolean getDoOutput() 返回此 URLConnection 的 doOutput 标志的值
long getExpiration() 返回 expires 头字段的值
String getHeaderField(int n) 返回第 n 个头字段的值
String getHeaderField(String name) 返回指定的头字段的值
long getHeaderFieldDate(String name, long Default) 返回解析为日期的指定字段的值
int getHeaderFieldInt(String name, int Default) 返回解析为数字的指定字段的值
String getHeaderFieldKey(int n) 返回第 n 个头字段的键
Map<String,List<String>> getHeaderFields() 返回头字段的不可修改的 Map
long getIfModifiedSince() 返回此对象的 ifModifiedSince 字段的值
InputStream getInputStream() 返回从此打开的连接读取的输入流
long getLastModified() 返回 last-modified 头字段的值
OutputStream getOutputStream() 返回写入到此连接的输出流
int getReadTimeout() 返回读入超时设置
Map<String,List<String>> getRequestProperties() 返回一个由此连接的一般请求属性构成的不可修改的 Map
String getRequestProperty(String key) 返回此连接指定的一般请求属性值
URL getURL() 返回此 URLConnection 的 URL 字段的值
boolean getUseCaches() 返回此 URLConnection 的 useCaches 字段的值
static String guessContentTypeFromName(String fname) 根据 URL 的指定 “file” 部分尝试确定对象的内容类型
static String guessContentTypeFromStream(InputStream is) 根据输入流的开始字符尝试确定输入流的类型
void setAllowUserInteraction(boolean allowuserinteraction) 设置此 URLConnection 的 allowUserInteraction 字段的值
void setConnectTimeout(int timeout) 设置一个指定的超时值(以毫秒为单位),该值将在打开到此 URLConnection 引用的资源的通信链接时使用
static void setContentHandlerFactory(ContentHandlerFactory fac) 设置应用程序的 ContentHandlerFactory
static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) 将未来的所有 URLConnection 对象的 allowUserInteraction 字段的默认值设置为指定的值
void setDefaultUseCaches(boolean defaultusecaches) 将 useCaches 字段的默认值设置为指定的值
void setDoInput(boolean doinput) 将此 URLConnection 的 doInput 字段的值设置为指定的值
void setDoOutput(boolean dooutput) 将此 URLConnection 的 doOutput 字段的值设置为指定的值
static void setFileNameMap(FileNameMap map) 设置 FileNameMap
void setIfModifiedSince(long ifmodifiedsince) 将此 URLConnection 的 ifModifiedSince 字段的值设置为指定的值
void setReadTimeout(int timeout) 将读超时设置为指定的超时值,以毫秒为单位
void setRequestProperty(String key, String value) 设置一般请求属性
void setUseCaches(boolean usecaches) 将此 URLConnection 的 useCaches 字段的值设置为指定的值
String toString() 返回此 URL 连接的 String 表示形式

使用示例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class URLConnectionDemo
{
   public static void main(String[] args)
   {
      try
      {
         // 以百度为例
         URL url = new URL("http://www.baidu.com");

         URLConnection connection = url.openConnection();
         // 设置连接超时时间
         connection.setConnectTimeout(10000);
         // 设置读超时时间
         connection.setReadTimeout(10000);
         // 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)
         connection.connect();

         // 获得响应状态信息
         String statusInfo = connection.getHeaderField(0);
         if (statusInfo != null)
         {
            // 解析状态信息,判断响应码是否为成功
            int index = statusInfo.indexOf(' ');
            if (!statusInfo.substring(index + 1).startsWith("200 "))
            {
               System.out.println("请求失败...");
               return;
            }
         }

         // 获得头信息
         Map<String, List<String>> headers = connection.getHeaderFields();
         Iterator<Entry<String, List<String>>> iterator = headers.entrySet()
               .iterator();
         while (iterator.hasNext())
         {
            Entry<String, List<String>> entry = iterator.next();
            System.out.println(entry.getKey() + ":" + entry.getValue());
         }

         System.out.println("响应内容如下:");
         // 内容是文本,直接以缓冲字符流读取
         BufferedReader reader = new BufferedReader(new InputStreamReader(
               connection.getInputStream(), "UTF-8"));
         String data = null;
         while ((data = reader.readLine()) != null)
         {
            System.out.print(data);
         }
         reader.close();
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
   }
}

HttpURLConnection

HttpURLConnection是URLConnection的子类,所以URLConnection中的方法,HttpURLConnection中都有,HttpURLConnection对URLConnection进行了扩展。
每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。

方法摘要

返回值 方法名 说明
abstract void disconnect() 指示近期服务器不太可能有其他请求。
InputStream getErrorStream() 如果连接失败但服务器仍然发送了有用数据,则返回错误流。
static boolean getFollowRedirects() 返回指示是否应该自动执行 HTTP 重定向 (3xx) 的 boolean 值。
String getHeaderField(int n) 返回 nth 头字段的值。
long getHeaderFieldDate(String name, long Default) 返回解析为日期的指定字段的值。
String getHeaderFieldKey(int n) 返回 nth 头字段的键。
boolean getInstanceFollowRedirects() 返回此 HttpURLConnection 的 instanceFollowRedirects 字段的值。
String getRequestMethod() 获取请求方法。
int getResponseCode() 从 HTTP 响应消息获取状态码。
String getResponseMessage() 获取与来自服务器的响应代码一起返回的 HTTP 响应消息(如果有)。
void setChunkedStreamingMode(int chunklen) 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
void setFixedLengthStreamingMode(int contentLength) 此方法用于在预先已知内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
static void setFollowRedirects(boolean set) 设置此类是否应该自动执行 HTTP 重定向(响应代码为 3xx 的请求)。
void setInstanceFollowRedirects(boolean followRedirects) 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向(响应代码为 3xx 的请求)。
void setRequestMethod(String method) 设置 URL 请求的方法, GET POST HEAD OPTIONS PUT DELETE TRACE 以上方法之一是合法的,具体取决于协议的限制。
abstract boolean usingProxy() 指示连接是否通过代理

使用示例

修改上面的示例如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class URLConnectionDemo
{
   public static void main(String[] args)
   {
      try
      {
         // 以百度为例
         URL url = new URL("http://www.baidu.com");

         HttpURLConnection connection = (HttpURLConnection) url
               .openConnection();
         // 设置连接超时时间
         connection.setConnectTimeout(10000);
         // 设置读超时时间
         connection.setReadTimeout(10000);
         // 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)
         connection.connect();

         // 获得响应状态信息
         if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
         {
            System.out.println("请求失败...");
            return;
         }

         // 获得头信息
         Map<String, List<String>> headers = connection.getHeaderFields();
         Iterator<Entry<String, List<String>>> iterator = headers.entrySet()
               .iterator();
         while (iterator.hasNext())
         {
            Entry<String, List<String>> entry = iterator.next();
            System.out.println(entry.getKey() + ":" + entry.getValue());
         }

         System.out.println("响应内容如下:");
         // 内容是文本,直接以缓冲字符流读取
         BufferedReader reader = new BufferedReader(new InputStreamReader(
               connection.getInputStream(), "UTF-8"));
         String data = null;
         while ((data = reader.readLine()) != null)
         {
            System.out.print(data);
         }
         reader.close();
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
   }
}
上一篇:【图像算法】彩色图像分割专题七:基于分水岭的彩色分割


下一篇:《教孩子学编程(Python语言版)》——1.5 编程挑战