使用URLConnection获取信息

使用URIConnection获取信息

如果想从某个Web资源获取更多信息,那么应该使用URLConnection类,它能得到比基本的URL类更多的控制功能。

使用URLConnection类的步骤如下

  1. 调用URL类中的openConnection方法获得URLConnection对象

    1
    URLConnection connection=url.openConnection();
  2. 使用以下方法来设置任意的请求属性

    1
    2
    3
    4
    5
    6
    7
    8
       setDoInput
    setDoOutput
    setIfModifiedSince
    setUseCaches//用于命令浏览器首先检查它的缓存
    setAllowUserInteraction//用于在访问有密码保护的资源时弹出对话框,以便查询用户名和口令
    setRequestProperty
    setConnectTimeout
    setReadTimeout
  1. 调用connect方法连接远程资源并获取响应头信息

    1
    connection.connect();
  2. 与服务器建立连接后,你可以查询头信息。getHeaderFieldKey和getHeaderField两个方法列举了消息头的所有字段。getHeaderFields方法返回一个包含了消息头中所有字段的标准Map对象。为了方便使用,以下方法可以查询各标准字段

    1
    2
    3
    4
    5
    6
    getContentType
    getContentLength
    getContentEncoding
    getDate
    getExpiration
    getLastModified
  3. 最后,访问资源数据。使用getInputStream方法获取一个输入流用以读入信息(这个输入流与URL类中的openStream方法返回的流相同)。

下面详细介绍一下URLConnection类中的一些方法。有几个方法可以在与服务器建立连接之前设置连接属性,其中最重要的是setDoInput和setDoOutput。在默认情况下建立的连接只有从服务器读取信息的输入流,并没有任何执行写操作的输出流。如果想获得输出流(例如,向一个Web服务器提交数据),那么可以调用:

1
connection.setDoOutput

下面也可以设置请求头。请求头是与请求命令一起被发送到服务器的

1
2
3
4
5
6
7
8
GET www.server.com/index.html HTTP/1.0
Referer: http://www.somewhere.com/links.html
Proxy-Connection: Keep-Alive
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.4)
Host: www.server.com
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: orangemilano=192218887821987

setIfModifiedSince方法用于告诉连接你只对某个特定日期以来被修改过的数据感兴趣;setUseCaches和setAllowUserInteraction这两个方法只作用于Applet;

还有一个总揽全局的方法:setRequestProperty,它可以用来设置对特定协议起作用的任何“名值对”

如果你想访问一个有保护的Web页,可以按照以下步骤操作

  1. 将用户名、冒号和口令以字符串形式连接在一起

    1
    String input=username+":"+password;
  1. 计算上一步所得字符串的base64编码。(base64编码用于将字节流编码成可打印的ASCII字符流。)

    1
    String encoding = base64Encode(input);
  2. 调用setRequestProperty方法,设置name参数的值为”Authorization”,value参数的值为“Base”+encoding:

    1
    connection.setRequestProperty("Authorization","Basic "+encoding);

一旦调用了connect方法,就可以查询响应头字段

1
2
3
4
String key=connection.getHeaderFieldKey(n);
//可以获得响应头的第n个键,其中n从1开始
//还可以使用以下方法获得第n个值
//String value= connection.getHeaderField(n);

getHeadreFields方法可以返回一个封装了响应头字段的Map对象

1
Map<String,List<String>> headerFields=connection.getHeaderFields();

HTTP响应头举例

1
2
3
4
5
6
7
Date: Wed,27 Aug 2008 00:15:48 GMT
Server: Apache/2.2.2(Unix)
Last-Modified: Sun, 22 Jun 2008 20:53:38 GMT
Accept-Ranges: bytes
Content-Length: 4813
Connection: close
Content-Type: text/html

java提供了六个访问响应头的常用方法

键名 方法名 返回类型
Date getDate long
Expires getExpiration long
Last-Modified getLastModified long
Content-length getContentLength int
Content-Type getContentType String
Content-Encoding getContentEncoding String

示例程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import java.io.*;
import java.net.*;
import java.util.*;

/**
* This program connects to an URL and displays the response header data and the first 10 lines of
* the requested data.
*
* Supply the URL and an optional username and password (for HTTP basic authentication) on the
* command line.
* @version 1.11 2007-06-26
* @author Cay Horstmann
*/
public class URLConnectionTest
{
public static void main(String[] args)
{
try
{
String urlName;
if (args.length > 0) urlName = args[0];
else urlName = "http://java.sun.com";

URL url = new URL(urlName);
URLConnection connection = url.openConnection();

// set username, password if specified on command line

if (args.length > 2)
{
String username = args[1];
String password = args[2];
String input = username + ":" + password;
String encoding = base64Encode(input);
connection.setRequestProperty("Authorization", "Basic " + encoding);
}

connection.connect();

// print header fields

Map<String, List<String>> headers = connection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : headers.entrySet())
{
String key = entry.getKey();
for (String value : entry.getValue())
System.out.println(key + ": " + value);
}

// print convenience functions

System.out.println("----------");
System.out.println("getContentType: " + connection.getContentType());
System.out.println("getContentLength: " + connection.getContentLength());
System.out.println("getContentEncoding: " + connection.getContentEncoding());
System.out.println("getDate: " + connection.getDate());
System.out.println("getExpiration: " + connection.getExpiration());
System.out.println("getLastModifed: " + connection.getLastModified());
System.out.println("----------");

Scanner in = new Scanner(connection.getInputStream());

// print first ten lines of contents

for (int n = 1; in.hasNextLine() && n <= 10; n++)
System.out.println(in.nextLine());
if (in.hasNextLine()) System.out.println(". . .");
}
catch (IOException e)
{
e.printStackTrace();
}
}

/**
* Computes the Base64 encoding of a string
* @param s a string
* @return the Base 64 encoding of s
*/
public static String base64Encode(String s)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
Base64OutputStream out = new Base64OutputStream(bOut);
try
{
out.write(s.getBytes());
out.flush();
}
catch (IOException e)
{
}
return bOut.toString();
}
}

/**
* This stream filter converts a stream of bytes to their Base64 encoding.
*
* Base64 encoding encodes 3 bytes into 4 characters. |11111122|22223333|33444444| Each set of 6
* bits is encoded according to the toBase64 map. If the number of input bytes is not a multiple of
* 3, then the last group of 4 characters is padded with one or two = signs. Each output line is at
* most 76 characters.
*/
class Base64OutputStream extends FilterOutputStream
{
/**
* Constructs the stream filter
* @param out the stream to filter
*/
public Base64OutputStream(OutputStream out)
{
super(out);
}

public void write(int c) throws IOException
{
inbuf[i] = c;
i++;
if (i == 3)
{
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[((inbuf[1] & 0x0F) << 2) | ((inbuf[2] & 0xC0) >> 6)]);
super.write(toBase64[inbuf[2] & 0x3F]);
col += 4;
i = 0;
if (col >= 76)
{
super.write('\n');
col = 0;
}
}
}

public void flush() throws IOException
{
if (i == 1)
{
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[(inbuf[0] & 0x03) << 4]);
super.write('=');
super.write('=');
}
else if (i == 2)
{
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[(inbuf[1] & 0x0F) << 2]);
super.write('=');
}
if (col > 0)
{
super.write('\n');
col = 0;
}
}

private static char[] toBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };

private int col = 0;
private int i = 0;
private int[] inbuf = new int[3];
}
Donate comment here