Android学习笔记----HttpURLConnection 和 HttpClient(已经被废弃)
16lz
2021-01-25
/*********** ****************************************************/ 使用 HTTP 协议访问网络
在 Android 上发送 HTTP 请求的方式一般有两种, HttpURLConnection 和 HttpClient.
HttpURLConnection
首先需要获取到 HttpURLConnection 的实例,一般只需 new 出一个 URL 对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可。
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
注意:如果URL传入的地址中含有中文,要对含有的中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文);
得到了 HttpURLConnection 的实例之后,我们可以设置一下 HTTP 请求所使用的方法。常用的方法主要有两个, GET 和 POST。 GET 表示希望从服务器那里获取数据 POST 则表示希望提交数据给服务器
connection.setRequestMethod("GET");
注意:其实GET方式也可以向服务器提交数据,如何通过GET方式提交数据,见最后GET方式提交数据
接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。这部分内容根据自己的实际情况进行编写
connection.setConnectTimeout(8000); //设置连接超时 connection.setReadTimeout(8000); //读取超时的毫秒数
获取连接状态码,如果状态码为200则表示连接成功
int status_code = connection.getResponseCode(); if(code == 200){ .........................................................................................
}
之后再调用 getInputStream()方法就可以获取到服务器返回的输入流了
InputStream in = connection.getInputStream();//获取到服务器返回的输入流了
剩下的任务就是对输入流进行读取,然后进行相关处理
public class StreamTool { /** * 把一个inputstream里面的内容转化成一个byte[] */ public static byte[] getBytes(InputStream is) throws Exception{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len = is.read(buffer))!=-1){ bos.write(buffer, 0, len); } is.close(); bos.flush(); byte[] result = bos.toByteArray(); return result; }}byte[] result = StreamTool.getBytes(in);//如果读取的是图片数据Bitmap bitmap = BitmapFactory.decodeByteArray(result,0,result.length);//也可以直接用Bitmap bitmap = BitmapFactory.decodeStream(in);......//如果读取的是网页数据,此处要注意网页的编码问题String temp = new String(result);if (temp.contains("gbk")) { String temp = new String(result, "gb2312"); .......................} else { .......................}
最后需要调用 disconnect()方法将这个 HTTP 连接关闭掉 connection.disconnect(); 实例:
private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SHOW_RESPONSE: String response = (String) msg.obj; // 在这里进行UI操作,将结果显示到界面上 } }};new Thread(new Runnable() {@Overridepublic void run() { HttpURLConnection connection = null; try { URL url = new URL("http://www.baidu.com"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); // 下面对获取到的输入流进行读取 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } Message message = new Message(); message.what = SHOW_RESPONSE; // 将服务器返回的结果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } } }}).start();
提交数据给服务器
将 HTTP 请求的方法改成 POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&符号隔开,比如说我们想要向服务器提交用户名和密码,就可以这样写:
connection.setRequestMethod("POST");//设置为POST方式DataOutputStream out = new DataOutputStream(connection.getOutputStream());out.writeBytes("username=admin&password=123456");//向服务器提交数据int code = conn.getResponseCode();//获取服务器返回的状态码,以此来判断数据是否提交成功if(code==200){ //数据提交成功,获取服务器返回的数据 InputStream in = conn.getInputStream(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(is)是自定义的流处理方法,见第一段实例代码 ........................................................................}
注意:如果传入的地址中含有中文,要对中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数); 同时如果要提交的数据中含有中文,要对提交的中文数据进行URL编码,否则传输数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(“张三”); out.writeBytes("username= "+ param1+ " &password=123456");//对于英文或者数字,进不进行URL编码应该没有什么影响
!!!!!!!HttpClient!!!!!!已经被废弃掉了
HttpClient
HttpClient 是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient 的实例
HttpClient httpClient = new DefaultHttpClient();
接下来如果想要发起一条 GET 请求,就可以创建一个 HttpGet 对象,并传入目标的网络地址,然后调用 HttpClient 的 execute()方法即可:
HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet);
注意:如果传入的地址参数中含有中文,要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数);
执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 }
接下来在这个 if 判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity 实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity 转换成字符串即可(也可以调用entity的getContent()实例方法,得到输入流),如下所示:
HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity);
或者
HttpEntity entity = httpResponse.getEntity(); InputStream in = entity.getContent(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
注意如果服务器返回的数据是带有中文的,直接调用 EntityUtils.toString()方法进行转换会有乱码的情况出现,这个时候只需要在转换的时候将字符集指定成 utf-8 就可以了,如下所示:
String response = EntityUtils.toString(entity, "utf-8");
实例:
private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SHOW_RESPONSE: String response = (String) msg.obj; // 在这里进行UI操作,将结果显示到界面上 } }};new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8"); Message message = new Message(); message.what = SHOW_RESPONSE; // 将服务器返回的结果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); } }}).start();
提交数据给服务器
创建一个 DefaultHttpClient 的实例
HttpClient httpClient = new DefaultHttpClient();
创建一个 HttpPost 对象,并传入目标的网络地址,如下所示:
HttpPost httpPost = new HttpPost("http://www.baidu.com");
注意:如果传入的地址参数中含有中文,要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数);
然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的 UrlEncodedFormEntity传入,如下所示:
List params = new ArrayList();params.add(new BasicNameValuePair("username", "admin"));params.add(new BasicNameValuePair("password", "123456"));UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");httpPost.setEntity(entity);
注意: 如果要 提交的数据中含有中文,要对提交的中文数据进行URL编码 ,否则传输数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(“张三”); params.add(new BasicNameValuePair("username", param1));
接下来的操作就和 HttpGet 一样了,调用 HttpClient 的 execute()方法,并将 HttpPost 对象传入即可:
HttpResponse httpResponse = httpClient.execute(httpPost);
执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功,接下来可以获取服务器的返回数据 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity); 或者 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity, "utf-8");//这样可以防止乱码问题 或者 HttpEntity entity = httpResponse.getEntity(); InputStream in = entity.getContent(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码 .........................................................................}
/*********** ****************************************************/
GET方式提交数据
HttpURLConnection的GET方式:
String path = "提交数据的服务器的地址"; String param1 = URLEncoder.encode(name); //对要传递的数据进行URL编码,防止出现乱码问题 String param2 = URLEncoder.encode(password); //对要传递的数据进行URL编码,防止出现乱码问题 URL url = new URL(path + "?name=" + param1 + "&password=" + param2);//如果path中含有中文参数的话,也要对path进行URL编码 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); // 只有调用getInputStream()方法的时候,数据才会被提交到服务器。 // 获取服务器返回的流信息 InputStream is = conn.getInputStream(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码 .........................................................................
HttpClient的GET方式:
//1. 获取到一个浏览器的实例 HttpClient client = new DefaultHttpClient(); //2. 准备请求的地址 String param1 = URLEncoder.encode(name); //对要传递的数据进行URL编码,防止出现乱码问题 String param2 = URLEncoder.encode(password); //对要传递的数据进行URL编码,防止出现乱码问题 HttpGet httpGet = new HttpGet(path + "?name=" + param1 + "&password=" + param2); //如果path中含有中文参数的话,也要对path进行URL编码 //3. 敲回车 发请求 HttpResponse ressponse = client.execute(httpGet); int code = ressponse.getStatusLine().getStatusCode(); if(code == 200){ InputStream is =ressponse.getEntity().getContent(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码 ..................................................................... } else{ ..................................................................... }
POST方式跟GET方式提交数据到服务器的区别:
get 一次提交的数据数据量比较小 4K 内部其实通过组拼url的方式 post 可以提交比较大的数据 form表单的形式 流的方式写到服务器 补充:
为了防止服务器端接收到的中文字符是乱码,在服务器端接收到的数据要注意编码问题。
String name = request.getParameter("name"); if(name!=null){ name =new String( name.getBytes("iso8859-1"),"utf-8"); }
服务器端对接收的字节流,按照 "iso8859-1" 进行编码生成字符串 , 所以对接收到的字符串,要按 "iso8859-1" 反编码成字节数组,再按UTF-8重新进行编码,生成中文字符。
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- 万字长文带你了解最常用的开源 Squid 代理服务器
- Nginx系列教程(一)| 手把手教你在Linux环境下搭建Nginx服务
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- android关于获取摄像头帧数据转成图片
- Android小程序之音乐播放列表
- Android(安卓)AsyncTaskLoader需要注意的问题