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通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具