HttpURLConnection

一 前言

       Get方法:通过Get方法向服务器提供数据是将数据加在url后面的。提供数据的方式是显式的。

       Post方法:通过Post向服务器提供数据的方式是隐式的,将数据通过getOutputStream().write(byte[] array)的方法传送给服务器。

  下面来总结一下通过Sun公司封装的HttpUrlConnection给服务器传送数据的步骤。

二 Get

(1)定义url字符串 
       即:将要访问的服务器网址定义为一个字符串,并在字符串的最后加“?”然后加上要传入的数据,如下:

String weatherPath = "http://www.sojson.com/open/api/weather/json.shtml?city=北京";

(2)生成URL  
       将定义的字符串生成一个URL类的对象,如下:

URL url = new URL(weatherPath);

(3)打开URL连接 并将其强制造型成HttpUrlConnection类型的对象。 
        通过URL与服务器建立连接。并将连接强制转换为HttpUrlConnection类型,
如下:

connection = (HttpURLConnection) url.openConnection();

(4)设置请求方式
        设置请求方式为”GET“类型, 
如下:

connection.setRequestMethod("GET");

(5)设置消息报头(可选)

            connection.setRequestProperty("Cache-Control","no-cache");
//表示接受数据的类型 如果可以接受的序列化的java对象,添加类型application/x-www-form-urlencoded
// connection.setRequestProperty("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
// "application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, " +
// "application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, " +
// "application/vnd.ms-powerpoint, application/msword,text/xml , text/html ,application/json ,*/*");
connection.setRequestProperty("Accept-Language","zh-cn");
connection.setRequestProperty("Accept-Charset","UTF-8");
//
connection.setRequestProperty("Accept-Encoding","gzip, deflate");
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Date",format.format(new Date(time)));
//指明实体正文的长度,以字节方式存储的十进制数字来表示
connection.setRequestProperty("Content-Length","23330");
//指明发送给接收者的实体正文的媒体类型
// connection.setRequestProperty("Content-Type","application/json,text/xml,text/html;charset=utf-8");

请求头大全

(6)设置超时时间 
由于服务器响应时间可能过长,所以可以设置超时时间:
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
(7)链接
connection.connect();
(8)获取状态码:
  int code = connection .getResponseCode() ;
 如果状态码为200,则表明可以正常访问服务器:
if (code == HttpURLConnection.HTTP_OK) { // 若响应码以2开头则读取响应头总的返回信息
.....
}
(9)获取读取的数据:
BufferedInputStream  bis = new BufferedInputStream(connection.getInputStream());
ByteArrayBuffer arrayBuffer = new ByteArrayBuffer(1024);
int length = -1;
while ((length = bis.read()) != -1) {
arrayBuffer.append(length);
}
result = EncodingUtils.getString(arrayBuffer.toByteArray(), "UTF-8");
Gson gson = new Gson();
final WeatherBean weatherBean = gson.fromJson(result,WeatherBean.class);
整体的代码如下:
   void getDataFromNet(){
long time = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH : mm : ss");
try {
// String weatherPath = "http://www.sojson.com/open/api/weather/json.shtml?city=北京";
URL url = new URL(weatherPath);
connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false); // 设置是否启用缓存,post请求不能使用缓存.
connection.setRequestMethod("GET");

connection.setRequestProperty("Cache-Control","no-cache");
//表示接受数据的类型 如果可以接受的序列化的java对象,添加类型application/x-www-form-urlencoded
// connection.setRequestProperty("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
// "application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, " +
// "application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, " +
// "application/vnd.ms-powerpoint, application/msword,text/xml , text/html ,application/json ,*/*");
connection.setRequestProperty("Accept-Language","zh-cn");
connection.setRequestProperty("Accept-Charset","UTF-8");
//
connection.setRequestProperty("Accept-Encoding","gzip, deflate");
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Date",format.format(new Date(time)));
//指明实体正文的长度,以字节方式存储的十进制数字来表示
connection.setRequestProperty("Content-Length","23330");
//指明发送给接收者的实体正文的媒体类型
// connection.setRequestProperty("Content-Type","application/json,text/xml,text/html;charset=utf-8");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
Map,List> listMap = connection.getRequestProperties();
Log.e("请求头部",listMap.toString());
connection.connect();
int code = connection.getResponseCode();
if (code == HttpURLConnection.HTTP_OK) { // 若响应码以2开头则读取响应头总的返回信息
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
ByteArrayBuffer arrayBuffer = new ByteArrayBuffer(1024);
int length = -1;
while ((length = bis.read()) != -1) {
arrayBuffer.append(length);
}
result = EncodingUtils.getString(arrayBuffer.toByteArray(), "UTF-8");
Gson gson = new Gson();
final WeatherBean weatherBean = gson.fromJson(result,WeatherBean.class);
updateUi(weatherBean);
} else { // 若响应码不以2开头则返回错误信息.
result = "error";
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}


三 Post

前面可以参考get请求步骤,不同的是设置请求方式:

connection.setRequestMethod("POST");

post请求往往需要传递参数,这就要打开网络的输出流来提交网络数据:

connection.setDoOutput(true);

再者就是提交参数:

dos = new DataOutputStream(connection.getOutputStream());
StringBuilder builder = new StringBuilder();
// attribute 为 HashMap
Set set = attribute.keySet();
Iterator stringIterator = set.iterator();
while (stringIterator.hasNext()){
String key = stringIterator.next();
String param = key + "=" + URLEncoder.encode(attribute.get(key)) + "&";
builder.append(param);
}
dos.writeBytes(builder.toString().substring(0, builder.toString().length() - 1));

整体的代码如下:

   void getNetDataByPost(String path , HashMap, String> attribute){
long time = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH : mm : ss");
try {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false); // 设置是否启用缓存,post请求不能使用缓存.
connection.setRequestMethod("POST");
connection.setRequestProperty("Cache-Control","no-cache");
//表示接受数据的类型 如果可以接受的序列化的java对象,添加类型application/x-www-form-urlencoded
// connection.setRequestProperty("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
// "application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, " +
// "application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, " +
// "application/vnd.ms-powerpoint, application/msword,text/xml , text/html ,application/json ,*/*");
connection.setRequestProperty("Accept-Language","zh-cn");
connection.setRequestProperty("Accept-Charset","UTF-8");
//
connection.setRequestProperty("Accept-Encoding","gzip, deflate");
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Date",format.format(new Date(time)));
//指明实体正文的长度,以字节方式存储的十进制数字来表示
// connection.setRequestProperty("Content-Length","23330");
//指明发送给接收者的实体正文的媒体类型
// connection.setRequestProperty("Content-Type","application/json,text/xml,text/html;charset=utf-8");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();

DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
StringBuilder builder = new StringBuilder();
// attribute 为 HashMap
Set set = attribute.keySet();
Iterator stringIterator = set.iterator();
while (stringIterator.hasNext()){
String key = stringIterator.next();
String param = key + "=" + URLEncoder.encode(attribute.get(key)) + "&";
builder.append(param);
}
dos.writeBytes(builder.toString().substring(0, builder.toString().length() - 1));

int code = connection.getResponseCode();
String result;
if (code == HttpURLConnection.HTTP_OK) { // 若响应码以2开头则读取响应头总的返回信息
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
ByteArrayBuffer arrayBuffer = new ByteArrayBuffer(1024);
int length = -1;
while ((length = bis.read()) != -1) {
arrayBuffer.append(length);
}
result = EncodingUtils.getString(arrayBuffer.toByteArray(), "UTF-8");
Gson gson = new Gson();
final WeatherBean2 weatherBean = gson.fromJson(result,WeatherBean2.class);
//更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
txt_http2.setText(weatherBean.getResult().getHeWeather5().get(0).getSuggestion().getUv().toString());
}
});
} else { // 若响应码不以2开头则返回错误信息.
result = "error";
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

四 关于HTTP请求GET和POST的区别 

1.GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据,多个参数用&连接;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。

  POST提交:把提交的数据放置在是HTTP包的包体<request-body>中。上文示例中红色字体标明的就是实际的传输数据

  因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变

 

2.传输数据的大小:

   首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:

   GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。

   因此对于GET提交时,传输数据就会受到URL长度的限制。

   POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。

 

3.安全性:

    POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存, (2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了。

示例代码。




你可能感兴趣的:(http)