您的位置:首页 > 理论基础 > 计算机网络

使用HttpURLConnection发送Post/Get请求

2015-11-06 14:22 537 查看
HTTP规范定义中最常用的请求类型就是Get和Post。当你在浏览器里输入任意一个网址按回车,浏览器即已经在执行Get请求了;当你回复了某条微博时,这时可能就执行了一次Post请求。简单的来说,Get就是向服务器发送索取数据的一种请求,不会影响资源的状态;Post是向服务器提交数据的一种请求,可能创建或更新服务器上的资源。访问服务器链接时,需要以链接地址为参数构造生成一个java.net.URL实例。URL由网络协议、主机名、端口、信息路径、引用等组成统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。URL的示例代码如下:
1
URL
url =
new
URL(
"http://www.devdiv.com:80/res/index.html#chapter1"
);
在上面的示例URL中,使用的协议为HTTP超文本传输协议;主机名为www.devdiv.com;端口为80,端口值不是必须要求的,当未指定端口号时则使用协议默认的端口;信息路径为"res/index.html";引用内容则是由"#"指示的"chapter1",表示在检索到指定的资源后,程序需要使用文档中附加有"chapter1"的标记部分。生成URL实例后,执行url.openConnection()方法可以获取HttpURLConnection对象。如果URL的协议属于以下包或其子包之一的公共、专用URLConnection子类:java.lang、java.io、java.util、java.net,则返回的连接将为该子类的类型。例如,对于HTTP,将返回HttpURLConnection,对于JAR,将返回JarURLConnection。代码如下:
1
HttpURLConnection
httpConn = (HttpURLConnection) url.openConnection();
通过代码获取的HttpURLConnection默认是进行Get请求,数据只读不提交。要使用Post方式提交数据,应提前设置好各项参数,代码如下:
1
httpConn.setDoInput(
true
);
2
httpConn.setDoOutput(
true
);
3
4
//
此方法在正式链接之前设置才有效。
5
httpConn.setRequestMethod(
"POST"
);
6
httpConn.setUseCaches(
false
);
7
//
正式创建链接
8
httpConn.connect();
setDoInput(boolean)参数值为true决定着当前链接可以进行数据读取,反之则不允许读取操作;setDoOutput(boolean)参数值为true时决定着当前链接可以进行数据提交工作,反之则不允许。setRequestMethod("POST")将当前HTTP请求方式设置为"POST",并在最后执行setUseCaches(boolean)取消了用户缓存。以上所有的工作都必须在正式创建链接之前进行。Post方式提交数据,需要用到数据输出流。当执行httpConn.connect()后,即可执行httpConn.getOutputStream()获取数据流从而进行数据写操作,为将数据提交到服务器作准备。代码如下:
1
DataOutputStream
dos =
new
DataOutputStream(httpConn.getOutputStream());
2
3
String
postContent = URLEncoder.encode(
"channel"
,
"UTF-8"
)
+
"="
+
URLEncoder.encode(
"Devdiv"
,
"UTF-8"
)
+
"&"
+
URLEncoder.encode(
"author"
,
"UTF-8"
)
+
"="
+
URLEncoder.encode(
"Sodino"
,
"UTF-8"
)
;
4
5
dos.write(postContent.getBytes());
6
dos.flush();
7
//
执行完dos.close()后,POST请求结束
8
dos.close();
数据是以<Key,Value>形式提交的,为保证数据的准确性,当数据是英文字母、数字时,原样发送;如果是空格则转换为"+",如果涉及到中文或其它字符,则通过URLEncoder.encode()进行BASE 64标准转码,得出"%XX"格式的加工数据,其中"X"为该符号以16进制表示的ASCII码。为保持数据的合法,本文所提交的内容虽皆为英文字符,但仍一致使用URLEncoder进行转码。当<Key,Value>数量不止一组时,组与组之间用"&"进行分隔。执行DataOutputStream.write(byte[])可以将所要提交的内容由输出流写入内存缓冲区中,在关闭输出流之前,执行一次flush()刷新操作,强制将可能未输出的数据及时写入内存缓冲区。对于同一个HttpURLConnection实例,只有执行完Post请求后,才允许Get请求进行,否则以Get请求进行的任何动作都将直接导致未执行的Post操作失败。从服务器上获取数据,同理,需要数据输入流,并循环读取所有数据后,方可加工出用户想要获取的信息。代码如下:
01
//
开始GET数据
02
String
encoding = httpConn.getContentEncoding();
03
is
= httpConn.getInputStream();
04
int
read
= -
1
;
05
baos
=
new
ByteArrayOutputStream();
06
while
((read
= is.read()) != -
1
)
{
07
baos.write(read);
08
}
09
byte
[]data = baos.toByteArray();
10
baos.close();
11
12
Stringcontent = 
null
;
13
if
(encoding!= 
null
)
{
14
content= 
new
String(data,encoding);
15
}
else
{
16
content= 
new
String(data);
17
}
读取过程中使用了ByteArrayOutputStream作为字节数据的缓冲流。当InputStream.read()返回值为-1表示数据已经全部读取完毕后,再将ByteArrayOutputStream中的缓冲数据由baos.toByteArray()一次性生成byte[],并根据一开始由httpConn.getContentEncoding()获取的字符编码类型,将byte[]构造成新的String。最后,所有的输入流、输出流都应该执行close()操作。在读取数据之前,可以获取当前链接的返回值、返回数据长度等等信息。在单纯的读取数据中,正常的返回值RespondCode等于HTTP_OK,需要链接跳转的返回值HTTP_MOVED_PERM/ HTTP_MOVED_TEMP,如果访问资源不存在,则返回值HTTP_NOT_FOUND。代码如下:
01
//获取代码返回值
02
int
respondCode= httpConn.getResponseCode()
03
//获取返回内容类型
04
Stringtype = httpConn.getContentType();
05
//获取返回内容的字符编码
06
String
encoding = httpConn.getContentEncoding();
07
//获取返回内容长度,单位字节
08
int
length= httpConn.getContentLength();
09
//获取头信息的Key
10
Stringkey = httpConn.getHeaderField(idx);
11
//获取完整的头信息Map
12
Map<String,List<String>> map = httpConn.getHeaderFields();
以上为完整的Post/Get请求过程。有时在简单的需求驱使下,服务器开发人员出于便捷性考虑,也会将Post请求方式交由Get请求方式替代实现。以同样需要向服务器发送两组<Key,Value>数据为需求,可以将此两组数据组合到url中,代码如下:
1
URL
url =
new
URL(
"http://www.devdiv.com:80/res/index.html?channel=Devdiv&author=sodino"
);
在完整的链接后,以"?"分隔url和传输数据,将<Key,Value>数据用"="组合成字符串后缀。然后依上面介绍的步骤向服务器发起请求,亦可读取正确的数据。同理,<Key,Value>在使用"="组合成字符串之前,仍需使用URLEncoder进行转码以保证数据的准确性。对于Post/Get所能发送的<Key,Value>的数据量大小,HTTP 1.1中并没有具体的限制,在实际运行中与程序运行环境及服务器部署设置有关。以上介绍了Post/Get的基本使用方法,由此可看出,由于Post方式将请求的数据放置在HTTP请求的正文内,它的安全性要比Get请求的安全性要高。比如:通过Get发送数据,用户名和密码信息都将会出现在URL上,在设置了浏览器缓存的情况下会被记录导致泄漏。所以在涉及到用户个人隐私的数据时,强烈推荐在将数据加密后使用Post方式提交至服务器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: