Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】

本文主要是介绍Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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请求必须设置允许输出 默认falseurlConn.setDoOutput(true);//设置请求允许输入 默认是trueurlConn.setDoInput(true);// Post请求不能使用缓存urlConn.setUseCaches(false);// 设置为Post请求urlConn.setRequestMethod("POST");//设置本次连接是否自动处理重定向urlConn.setInstanceFollowRedirects(true);// 配置请求Content-TypeurlConn.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=13468857714
Post方式请求参数params--->pwd=e10adc3949ba59abbe56e057f20f883e&username=13468857714
Post方式请求成功,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网络请求框架。

这篇关于Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995999

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法