HttpURLConnection发送Get和Post请求
HttpURLConnection是java的标准类,可发送get请求和post请求。
关于Get和Post的区别,这里就不细说了,网上普遍的说法是:
1、GET请求是从服务器上获取数据,POST请求是向服务器传送数据。
2、GET的请求参数放在URL链接中,POST的请求参数放在body中。
3、GET的URL会有长度上的限制,则POST的数据则可以非常大。
4、POST比GET安全,因为数据在地址栏上不可见。
5、· · · · · ·
以上所述的区别,都不是HTTP协议强制要求的,感兴趣的话可以详细去了解,一定能收获很多的,但是归根结底都是HTTP请求,类似的还有PUT、DELETE等等的方式。
好了,还是来说说代码的使用
测试类,分别打印GET请求的结果和POST请求的结果
public class test {
private final static String HTTP_URL = "http://localhost:8080/mycomputer";
private static HashMap<String, String> mData = new HashMap<String, String>();
public static void main(String[] args) {
mData.put("name", "HongBin");
mData.put("sax", "male");
System.out.println("GetResult:" + startGet(HTTP_URL));
System.out.println("PostResult:" + startPost(HTTP_URL));
}
}
Get请求:
private static String startGet(String path){
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
//GET请求直接在链接后面拼上请求参数
String mPath = path + "?";
for(String key:mData.keySet()){
mPath += key + "=" + mData.get(key) + "&";
}
URL url = new URL(mPath);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
//Get请求不需要DoOutPut
conn.setDoOutput(false);
conn.setDoInput(true);
//设置连接超时时间和读取超时时间
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//连接服务器
conn.connect();
// 取得输入流,并使用Reader读取
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
//关闭输入流
finally{
try{
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result.toString();
}
Post请求:
private static String startPost(String path){
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("Post");
// 发送POST请求必须设置为true
conn.setDoOutput(true);
conn.setDoInput(true);
//设置连接超时时间和读取超时时间
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
out = new OutputStreamWriter(conn.getOutputStream());
// POST的请求参数写在正文中
for(String key:mData.keySet()){
out.write(key + "=" + mData.get(key) + "&");
}
out.flush();
out.close();
// 取得输入流,并使用Reader读取
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
//关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result.toString();
}
注意点:
1. 因为HttpURLConnection是一个抽象类,所以不能被直接实例化,通过URL.openConnection()方法得到HttpURLConnection的父类,然后再强转成HttpURLConnection对象实例。
2. 无论是post请求还是get请求,connect()函数实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。但是也可以不通过connect()方法来建立连接,因为getOutputStream()方法会隐式的进行connect。
3. 方法的调用顺序非常重要,对connection对象的一切配置(就是各种set方法)必须在connect()方法之前调用,getOutputStream()方法必须在getInputStream()之前调用。
4. 前面说到了各种方法的调用顺序,那么为什么要这样呢。首先HttpURLConnection对象被创建,然后被指定各种选项(例如连接超时时间,是否使用缓存,是否读取输出流等),然后与服务端建立连接。如果已经连接成功再设置这些选项将会报错。
5. post请求参数是放在正文里面的,正文通过outputStream流写入的,实际上outputStream是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。即使outputStream流没有关闭,在调用getInputStream()之后再写入参数也无效了。