欢迎光临
我们一起进阶

Java网络编程(十一):URLConnection

扫码或搜索:沉默王二
发送 290992
即可立即永久解锁本站全部文章

URLConnection是一个抽象类,表示指向URL指定资源的活动连接。URLConnection有两个不同但相关的用途。首先,与URL类相比,它对服务器的交互提供了更多的控制。URLConnection可以检查服务器发送的头部,并相应地做出响应。它可以设置客户端请求中使用的头部字段。最后,URLConnection可以用 post、put和其他HTTP请求方法向服务器发送数据。

其次,URLConnection类是Java的协议处理器机制的一部分,这个机制还包括URLStreamHandler类。协议处理器的思想很简单:它们将处理协议的细节与处理特定数据类型分开,提供相应的用户接口,并完成完整 Web 浏览器所完成的其他操作。

打开URLConnection

直接使用URLConnection类的程序遵循以下基本步骤:

  • 构造一个URL- 对象;
  • 调用这个URL对象的openConnection()获取一个对应该URL的URLConnection对象;
  • 配置这个URLConnection;
  • 读取首部字段;
  • 获得输入流并读取数据;
  • 获得输出流并写入数据;
  • 关闭连接;

并不一定执行所有这些步骤。看你需不需要!
URLConnection类仅有的一个构造函数为保护类型:

protected URLConnection(URL url)
1
try {
            URL url = new URL("http://www.baidu.com");
            URLConnection connection = url.openConnection();
            //从URL读取。。。
        } catch (Exception e) {
            // TODO: handle exception
        }

读取服务器的数据

下面是使用URLConnection对象从一个URL获取数据所需的最起码的步骤:

  • 构造一个URL对象;
  • 调用这个URL对象的openConnection()方法,获取对应该该URL的URLConnection对象;
  • 调用这个URLConnection的getInputStream()方法;
  • 使用通常的流API读取输入流;

getInputStream()方法返回一个通用InputStream,可以读取和解析服务器发送的数据:

public class Test {

    public static void main(String[] args) {
        try {
            //打开URLConnection进行读取
            URL url = new URL("http://www.itmind.net");
            URLConnection connection = url.openConnection();
            try (InputStream in = connection.getInputStream()){    //带资源的try-catch语句。自动关闭
                InputStream buffer = new BufferedInputStream(in);
                //将InputStream串链到一个Reader
                Reader reader = new InputStreamReader(buffer);
                int c;
                while ((c = reader.read())!= -1) {
                    System.out.print((char)c);
                }
            } catch (MalformedURLException e) {

            }
        } catch (IOException e) {

        }
    }   
}

URL和URLConnection这两个类最大的不同在于:

  • URLConnection提供了对HTTP首部的访问;
  • URLConnection可以配置发送给服务器的请求参数;
  • URLConnection除了读取服务器数据外,还可以向服务器写入数据;

读取指定的首部字段

前6个方法可以请求首部中特定的常用字段:

  • Content-Type
  • Content-Length
  • Content-encoding
  • Date
  • Last-modified
  • Expires

public String getContentType()

getContentType()方法返回响应主体的MIME内容类型。如果没有提供内容类型,它不会抛出异常,而是返回null;

public int getContentLength()

getContentLength()方法告诉你内容中有多少字节。如果没有Content-Length首部,getContentLength()就返回-1;

public long getContentLengthLong()——–Java7增加的

与getContentLength()类似,只不过它会返回一个long而不是int,这样就可以处理更大的资源;

public String getContentEncoding()

getContentEncoding()方法返回一个String,指出内容是如何编码的。如果发送的内容没有编码,这个方法就返回null;

public long getDate()

getDate()方法返回一个long,指出文档何时发送;

public long getExpiration()

有些文档有基于服务器的过期日期,指示应当何时从缓存中删除文档,并从服务器重新下载。如果HTTP首部没有包括Expiration字段,getExpiration()就返回0,这表示文档不会过期,将永远保留在缓存中;

public long getLastModified()

返回文档的最后修改日期;

示例如下:

public class Test {

    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.baidu.com");
            URLConnection connection = url.openConnection();
            System.out.println("Content-Type: " + connection.getContentType());
            System.out.println("Content-Length: " + connection.getContentLength());
            System.out.println("Content-LengthLong: " + connection.getContentLengthLong());
            System.out.println("Content-encoding: " + connection.getContentEncoding());
            System.out.println("Date: " + connection.getDate());
            System.out.println("Expires: " + connection.getExpiration());
            System.out.println("Last-modified: " + connection.getLastModified());
        } catch (IOException e) {

        }
    }   
}

获取任意首部字段

public String getHeaderField(String name)

getHeaderField()方法返回指定首部字段的值。首部的名不区分大小写,也不包含结束冒号;

URL url = new URL("http://www.itmind.net");
URLConnection connection = url.openConnection();
System.out.println(connection.getHeaderField("Content-Type"));
System.out.println(connection.getHeaderField("last-modified"));

//输出
//text/html
//Mon, 23 Jan 2017 13:27:36 GMT

public String getHeaderFieldKey(int n)

返回第n个首部字段的键(即字段名)。请求方法本身是第0个首部,它的键为null。第一个首部即编号为1:

System.out.println(connection.getHeaderFieldKey(5)); //输出Content-Type

public String getHeaderField(int n)

返回第n个首部字段的值,包含请求方法和路径的起始行是第0个首部字段,实际的第一个首部编号为1。来看示例。

public class Test {

    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.baidu.com");
            URLConnection connection = url.openConnection();
            for (int i = 1; ; i++) {
                String header = connection.getHeaderField(i);
                if (header == null) {
                    break;
                }
            System.out.println(connection.getHeaderFieldKey(i)+": "+header);    
            }
        } catch (IOException e) {

        }
    }   
}

//输出
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 2381
Content-Type: text/html
Date: Thu, 04 Oct 2018 13:14:20 GMT
Etag: "588604ec-94d"
Last-Modified: Mon, 23 Jan 2017 13:28:12 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/

public long getHeaderFieldDate(String name, long Default)

这个方法首先获取由name参数指定的首部字段,然后尝试将这个字符串转换为一个long;

public long getHeaderFieldInt(String name, int Default)

这个方法获取首部字段name的值,尝试将其转换为int;

赞(0) 打赏
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

小白学堂,学的不止是技术,更是前程

关于我们免责声明

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏