主线程中不能访问网络,这是在Android4.0之后加入的概念
HttpURLConnection:
请求URL(Request URL)
上图中的Request URL就是请求的Url地址,即https://www.baidu.com,该Url没有附加其他的参数。其实可以通过?和&符向URL地址后面追加一系列的键值对参数,比如地址https://www.baidu.com/s?ie=utf-8&wd=Android,该Url包含两个键值对,ie=utf-8,以及wd=Android,ie和wd是key,utf-8和Android分别是其对应的value,服务端可以获取ie和wd所对应的value的值。由此我们可以看出,Url可以携带额外的数据信息。一般情况下,URL的长度不能超过2048个字符,即2KB,超过此限制的话服务器可能就不识别。
请求体(Request Body)
之前我们提到,URL的最大长度就是2048个字符,如果我们发送的数据很大,超过了2KB怎么办?我们可以将很大的数据放到请求体中,GET请求不支持请求体,只有POST请求才能设置请求体。请求体中可以放置任意的字节流,从而可以很方便地发送任意格式的数据,服务端只需要读取该输入流即可。
服务器接收到客户端发来的请求后,会进行相应的处理,并向客户端输出信息,输出的信息包括响应头和响应体。响应体是服务端向客户端传输的实际的数据信息,本质就是一堆字节流,可以表示文本,也可以表示图片或者其他格式的信息。
GET:
我们之前提到,当发送键值对信息时,可以在URL上面直接追加键值对参数。当用GET请求发送键值对时,键值对会随着URL一起发送的。
由于GET请求发送的键值对时随着URL一起发送的,所以一旦该URL被黑客截获,那么就能看到发送的键值对信息,所以GET请求的安全性很低,不能用GET请求发送敏感的信息(比如用户名密码)。
由于URL不能超过2048个字符,所以GET请求发送数据是有长度限制的。
由于GET请求较低的安全性,我们不应该用GET请求去执行增加、删除、修改等的操作,应该只用它获取数据。
POST:
POST请求的URL中追加键值对参数,不过这些键值对参数不是随着URL发送的,而是被放入到请求体中发送的,这样安全性稍微好一些。
应该用POST请求发送敏感信息,而不是用GET。
由于可以在请求体中发送任意的数据,所以理论上POST请求不存在发送数据大小的限制。
当执行增减、删除、修改等操作时,应该使用POST请求,而不应该使用GET请求。
发送get请求:
//发送GET请求 url = new URL("http://192.168.31.200:8080/HttpServer/MyServlet?name=孙群&age=27"); conn = (HttpURLConnection) url.openConnection(); //HttpURLConnection默认就是用GET发送请求,所以下面的setRequestMethod可以省略 conn.setRequestMethod("GET"); //HttpURLConnection默认也支持从服务端读取结果流,所以下面的setDoInput也可以省略 conn.setDoInput(true); //用setRequestProperty方法设置一个自定义的请求头:action,由于后端判断 conn.setRequestProperty("action", NETWORK_GET); //禁用网络缓存 conn.setUseCaches(false); //获取请求头 requestHeader = getReqeustHeader(conn); //在对各种参数配置完成后,通过调用connect方法建立TCP连接,但是并未真正获取数据 //conn.connect()方法不必显式调用,当调用conn.getInputStream()方法时内部也会自动调用connect方法 conn.connect(); //调用getInputStream方法后,服务端才会收到请求,并阻塞式地接收服务端返回的数据 InputStream is = conn.getInputStream(); //获取URL连接的输入流,从而获取响应的内容 //将InputStream转换成byte数组,getBytesByInputStream会关闭输入流 responseBody = getBytesByInputStream(is); //获取响应头 responseHeader = getResponseHeader(conn);
一个使用实例:
try { URL httpUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection(); } catch (Exception e) { e.printStackTrace(); } String result = ""; try { InputStreamReader input = new InputStreamReader(conn.getInputStream()); BufferedReader buffer = new BufferedReader(input); while ((inputLine = buffer.readLine()) != null) result += inputLine + "\n"; buffer.close(); } catch (Exception e) { e.printStackTrace(); } return result;
以Post方式向服务器发送请求,提交参数给服务器:
try { URL httpUrl = new URL(url); conn = (HttpURLConnection) httpUrl.openConnection(); } catch (Exception e) { e.printStackTrace(); } String result = ""; try { conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setUseCaches(false); OutputStream out = conn.getOutputStream(); print = new PrintWriter(out); print.print(params); print.flush(); InputStreamReader input = new InputStreamReader( conn.getInputStream()); BufferedReader buffer = new BufferedReader(input); String inputLine = null; while ((inputLine = buffer.readLine()) != null) result += inputLine + "\n"; print.close(); buffer.close(); } catch (Exception e) { e.printStackTrace(); } return result;
HttpClient:
在API 23中,Google已经移除了移除了Apache HttpClient相关的类 。谷歌推荐使用HttpUrlConnection,如果要继续使用需要Apache HttpClient,有两种方法。
- Eclipse下libs里添加org.apache.http.legacy.jar,
- Android studio里在相应的module下的build.gradle中加入即可。
android {
useLibrary 'org.apache.http.legacy'
}