导语
java.net.HttpURLConnectin类是URLConnection类的抽象子类。它在处理协议为HTTP的URL时特别有效。具体而言,它通过它可以获取和设置请求方法,确定是否重定向,获取响应码和消息体,以及是否使用代理。由于这个类是一个抽象类,所以不能直接创建它的实例。不过可以通过强转的方式来获取 HttpURLConnection对象。
获取一个HttpURLConnection对象
URL url = new URL("http://www.xdysite.cn/index.php");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
请求方法
HTTP请求中的常用方法包含一下几个
- GET
- POST
- HEAD
- PUT
- DELETE
HEAD
HEAD方法是最简单的方法。这个方法和GET方法很类似。不过,它告诉服务器只返回HTTP首部,不用实际发送消息体。这个方法最常见的用途是检查当前客户端缓存的文件是否与服务器一致(服务器可能会对文件做修改操作)。下面是个使用HEAD请求方法的简单程序,它会显示服务器中一个文件最后一次修改时间。
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://www.xdysite.cn/index.html");
try {
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("HEAD");
System.out.println("该资源最后一次修改时间"+ new Date(http.getLastModified()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
执行结果
服务器资源
http://cgblb.img48.wal8.com/img48/563395_20161212173407/s/148163323406_medium.jpg
这里并不一定非要使用HEAD方法,也可以利用GET来得到同样的结果。不过使用GET方式的话,服务器会发送该资源。而我们只关心首部中的文件的最后修改时间而已。
DELETE
DELETE方法将删除Web服务器上位于指定URL的文件。由于这个请求存在明显的安全风险,所以并非所有的服务器都配置支持这个方法,即使支持该方法通常也需要进行身份认证。典型的请求方式如下:
DELETE /javafaq/2016march.html HTTP/1.1
Host: www.xdysite.cn
Accept: text/html,image/gif,image/jpeg,*;q=0.2
Connection: keep-alive
如果服务器接受这个请求,其响应也与实现有关。有的服务器会删除文件,有的则会将文件放到回收站中。另外一些则只是将这个文件标记为不可读。
PUT
如果我们需要将文件放到Web服务器上,则可以采用该方法。这个方法允许客户端放在网站的抽象层次结构中,而不需要知道网站是如何映射到具体的本地文件系统的。这与FTP正相反,FTP用户必须知道实际的目录结构,而不是服务器的虚拟目录结构。下面显示如何利用PUT方式将一个文件放在Web服务器上
PUT /blog/wp-app.php/service/testput.html HTTP/1.1
Host: www.xdysite.cn
Content-Type: application/xml;type=entry
Content-Length: 329
If-Match: "ertr2361fgt9733"
<?xml version="1.0">
<entry>
<title>The Power of Pomodoros</title>
<author><name>Elliotte Harold</name></author>
</entry>
与删除文件一样,PUT通常也需要进行某种身份认证。而大多数服务器须配置为支持PUT方式
HTTP长连接
HTTP1.1支持长连接,允许通过一个TCP socket发送多个请求和相应。在请求头和响应头中需要显示包含Connection: Keep-Alive元数据。HTTPURLConnection类透明的支持HTTP keep-alive,即默认情况下长连接是打开的。在服务器关闭连接之前,如果再次连接同一个服务器,它会重用socket。
流模式
每个发送给HTTP服务器的请求都有一个HTTP首部。首部中有一个Content-lenght字段,即请求主体中的字节数。不过,写入首部,需要知道主体的长度,但是在写首部的时候可能还不知道主体的长度。正常情况下,对于这个两难的问题,JAVA的解决办法是:对于从HTTPURLConnection获取的OutputStream,会将写入此流的所有内容进行缓存,直到流关闭。此时它就知道主体中有多少个字节了。
这种模式对于表单的短请求很合适。不过,对于非常长的表单或一些SOAP消息,相应时负担很大。因为要缓存整个数据。JAVA为这个问题提供了两个解决方案。如果知道数据的大小,则可以将数据大小告诉HTTPURLConnection对象。如果预先不知道数据大小,则可以使用分块传输方式。
public void setFixedLengthStreamingMode(long contentLength)
通过该API可以告诉HttpURLConnection数据的大小。这样JAVA就会在HTTP首部的Content-Length字段中使用这个数。不过如果最终写入的数据多于或少于这个字节数,则会抛出一个IOException。
public void setChunkedStreamingMode(int chunkLength)
在使用该API设置好块的大小后,然后我们可以通过OutputStream发送数据。每当缓存中的数据量累计到设定的值后,java就会把缓存的中的数据输出。这是数据的发送方式就是块方式(chunked)。