Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】
来源:互联网 发布:淘宝怎么查看旺旺号 编辑:程序博客网 时间:2024/05/17 07:36
URLConnection是个抽象类,它有两个直接子类分别是HttpURLConnection和JarURLConnection。另外一个重要的类是URL,通常URL可以通过传给构造器一个String类型的参数来生成一个指向特定地址的URL实例。
每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。
需求,发起一个Post请求,并携带参数给服务器,服务器返回Json数据
代码实现
import java.io.*;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLEncoder;import java.util.HashMap;/** * Created by yuandl on 2016-10-18. * HttpURLConnection测试 */public class URLConnectionTest { public static void main(String[] args) { String url = "http://10.58.178.72/intco/mobi/member/login"; HashMap<String, String> params = new HashMap<>(); params.put("username", "13468857714"); params.put("pwd", MD5.md5("123456").toLowerCase()); requestPost(url, params); } /** * Post请求 * * @param httpUrl * @param paramsMap */ private static void requestPost(String httpUrl, HashMap<String, String> paramsMap) { try { String baseUrl = httpUrl; //合成参数 StringBuilder tempParams = new StringBuilder(); int pos = 0; for (String key : paramsMap.keySet()) { if (pos > 0) { tempParams.append("&"); } tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8"))); pos++; } String params = tempParams.toString(); System.out.println("Post方式请求地址httpUrl--->" + params); System.out.println("Post方式请求参数params--->" + params); // 请求的参数转换为byte数组 byte[] postData = params.getBytes(); // 新建一个URL对象 URL url = new URL(baseUrl); // 打开一个HttpURLConnection连接 HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); // 设置连接超时时间 urlConn.setConnectTimeout(5 * 1000); //设置从主机读取数据超时 urlConn.setReadTimeout(5 * 1000); // Post请求必须设置允许输出 默认false urlConn.setDoOutput(true); //设置请求允许输入 默认是true urlConn.setDoInput(true); // Post请求不能使用缓存 urlConn.setUseCaches(false); // 设置为Post请求 urlConn.setRequestMethod("POST"); //设置本次连接是否自动处理重定向 urlConn.setInstanceFollowRedirects(true); // 配置请求Content-Type urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 开始连接 urlConn.connect(); // 发送请求参数 DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream()); dos.write(postData); dos.flush(); dos.close(); // 判断请求是否成功 if (urlConn.getResponseCode() == 200) { // 获取返回的数据 String result = streamToString(urlConn.getInputStream()); System.out.println("Post方式请求成功,result--->" + result); } else { System.out.println("Post方式请求失败"); } // 关闭连接 urlConn.disconnect(); } catch (Exception e) { e.printStackTrace(); } } /** * 将输入流转换成字符串 * * @param is 从网络获取的输入流 * @return */ public static String streamToString(InputStream is) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } baos.close(); is.close(); byte[] byteArray = baos.toByteArray(); return new String(byteArray); } catch (Exception e) { e.printStackTrace(); return null; } }}
- 打印结果
Post方式请求地址httpUrl--->pwd=e10adc3949ba59abbe56e057f20f883e&username=13468857714Post方式请求参数params--->pwd=e10adc3949ba59abbe56e057f20f883e&username=13468857714Post方式请求成功,result--->{"status":1,"data":{"mId":"426e743224db4ecb8313e069982a7496","mName":"*东亮","pwd":"f241426298243cb7f6f97da58749ffb386c1457d","sex":"1","mobile":"13468857714","authentication":"0","personal":"0","isMain":"1","parentId":"0","newOrold":"1","imgurl":"http://10.58.178.72/intco/upload/img/member/portrait/2016/10/9331f754fbb742d99f6e61dcee0fe61d.jpg","state":"1","rongcloud_token":"1XHoYMAzlXidThqzyftV8at+qlfSNm8M8gqvzen0AUEV4lvsXAvmBJF0GQBkh5JP1I3XDUvd60sWEglC4+KRsnv5d+pcovzErw8ekgl7y6fM3gYaOuFDcqN0iaV2F2PAOM4jDTjH9M8="},"msg":"登录成功!"}
- 总结
- HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
- 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。 这些顺序实际上是由http请求的格式决定的。
- http请求实际上由两部分组成, 一个是http头,所有关于此次http请求的配置都在http头里面定义, 一个是正文content。 connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前, 就必须把所有的配置准备好。
- 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络, 而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。 至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求 正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数 之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改) 都是没有意义的了,执行这些操作会导致异常的发生。
- 分析
HttpURLConnection是Java层提供的标准网络请求工具类,可以实现各种功能。通过以上的代码和返回的请求结果可以知道,我们知道其实在Android中无论什么网络请求框架,最底层也是这样去实现的。我们可以在这个上面继续封装,不断完善就可以成为一个轻量级的Android网络请求框架。
1 0
- Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】
- Android HTTP协议请求网络(三)之HttpURLConnection方式
- 请求网络之HttpUrlConnection
- 网络请求测试之HttpUrlConnection【Android】
- android网络编程之HttpUrlConnection--POST请求
- Android探索之HttpURLConnection网络请求
- Android中的网络请求之HttpURLConnection
- Android网络请求框架剖析一、Okhttp
- http网络请求框架
- 网络请求之HttpURLConnection 简述
- android HttpURLConnection网络请求数据
- android 请求网络数据 HttpURLConnection
- Android基于HttpURLConnection网络请求
- android网络请求HttpURLConnection详解
- Android网络请求框架android-async-http
- Android网络框架之Http请求的分发与执行
- Android知识点之网络底层封装:细数常用的网络请求框架
- Android Http接地气网络请求(HttpURLConnection)
- codeforces 546D (数学 水)
- #ifdef DEBUG的理解
- 单删,批删,全选,反选
- 微软公司内部培训程序员资料---求解线性方程组的类
- 常用软件的下载
- Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】
- fastdfs 上传大小限制调整
- 程序员创造了世界,世界欠程序员一个1024。
- systemctl start mesos-slave problem
- Android 构建 Material Design 应用
- Smartisian M1发布会
- 谷歌Cartographer学习(1)-快速安装测试
- 题型:编写一段JS代码提取URL中的各个GET参数,并按Key_Value的形式返回到一个对象中(如:Json结构)
- 红米3 roo遇到的坎?