HttpComponents入门解析

2023-11-14

 

1 简介

    超文本传输协议(http)是目前互联网上极其普遍的传输协议,它为构建功能丰富,绚丽多彩的网页提供了强大的支持。构建一个网站,通常无需直接操作http协议,目前流行的WEB框架已经透明的将这些底层功能封装的很好了,如常见的J2EE, .NET, php等框架或语言。

除了作为网站系统的底层支撑,http同样可以在其它的一些场景中使用,如游戏服务器和客户端的传输协议、web service、 网络爬虫、HTTP代理、网站后台数据接口等。

Http Components 对HTTP底层协议进行了很好的封装,如果你是一个J2EE、.net或php程序员,对下面涉及的概念可能不会陌生。

 

2 httpComponents组件结构

HttpComponents Core

    简称HttpCore, 是一组底层Http传输协议组件,支持两种I/O模型,阻塞I/O模型和和非阻塞I/O模型。上层组件(HttpComponents Client, HttpComponents AsyncClient)依赖此组件实现数据传输。

阻塞I/O模型基于基本的JAVA I/O实现,非阻塞模型基于JAVA NIO实现。

HttpComponents Client

建立在HttpCore之上的Http客户端管理组件。底层基于HttpCore 阻塞I/O。从Commons HttpClient 3.x 继承而来,Commons HttpClient原来是apache commons组建的一部分,现在被HttpComponents Client所替代了。

    原始的Commons HttpClient 3.x可以在http://hc.apache.org/httpclient-legacy/index.html找到。

 

HttpComponents AsyncClient

    建立在HttpCore NIO模型之上的Http客户端,与基于阻塞I/O的HttpComponents Client形成互补,由于底层使用的NIO非阻塞模型,所以适用于高性能的应用场景。

 

开始使用HttpComponents组件

    首先打开http://hc.apache.org/,点击左侧的Download链接,进入下载页面,下载最新版本的HttpComponents。在编写本文时最新版本是4.1.2。解压缩下载到的压缩包,lib目录下是HttpComponents和它依赖的类库,将它们放到你的工程classpath中,如果依赖文件已经存在了,不要放置多份,以免类库之间的冲突。

然后需要检查一下工程的classpath中是否存在commons http包。Commons http与HttpComponents是完全两个东西,HttpComponents中的Client是从Commons http继承而来的,所以很多类名是相同的。为了避免出现莫名奇妙的问题,应将Commons http从工程中删除(当然,如果你认为自己足够聪明,也可以在引用java包时小心区分)。

Commons http类库的包是org.apache.commons.httpclient

HttpComonents类库的包是org.apache.http

3 Get请求

    Get、Post是最常见的获取网页内容的请求形式,当然,返回内容并非必须是html代码,任何的xml、json或文字字符串都可以作为返回内容。

下面是用Get请求获取一个html网页内容的代码

 

 

// (1) 创建HttpGet实例
HttpGet get = new HttpGet("http://www.126.com");

// (2) 使用HttpClient发送get请求,获得返回结果HttpResponse
HttpClient http = new DefaultHttpClient();
HttpResponse response = http.execute(get);

// (3) 读取返回结果
if (response.getStatusLine().getStatusCode() == 200) {
    HttpEntity entity = response.getEntity();

    InputStream in = entity.getContent();
    readResponse(in);
}

  

(1)HttpGet的实例就是一个get请求,构造函数只有一个字符串参数,即要获取的网页地址。另外一种构造形式是使用URI实例作为HttpGet的参数。HttpComponents提供了URIUtils类,它的createURI()返回一个URI实例,将请求地址拆分构造不失为一种更加清晰的方式。

    URI uri = URIUtils.createURI("http", "www.126.com", 80, "/", "", null);
    HttpGet get = new HttpGet(uri);

 

(2)请求最后被HttpClient发送出去,new DefaultHttpClient()创建一个基本的HttpClient实例。由于底层是基于阻塞的JAVA I/O模型,执行execute()的时间与具体请求的远程服务器和网络速度有关,在实际运行场景中应特别注意此问题。如果是在tomcat等环境中执行可能会造成线程等待,浪费服务器资源,或拒绝其它的连接。

 

(3)请求返回后就可以读取返回内容了,但有一个前提是此次请求是否真的成功了?服务器地址错误,或请求的页面不存在等问题都会让请求失败。为了确保得到了正确的响应首先应判断返回码是否正确。调用response.getStatusLine()返回一个StatusLine的实例,此实例描述了一次请求的响应信息。一个成功响应的StatusLine实例本身包含如下信息:

 

    HTTP/1.0 200 OK

 

HTTP/1.0:是请求协议和版本号

200:是响应码

 

StatusLine的下面2个方法分别用于获取响应信息的各部分内容

getProtocolVersion(): 得到请求协议和协议版本号,如HTTP/1.0

getStatusCode():得到响应码,如200

 

HttpEntity entity = response.getEntity()返回一个HttpEntity实例,进而调用getContent()就得到了一个输入流。后面的事情应该很明确了。readResponse()是一个自己写的读取输入流中字符串的方法,代码如下:

public static void readResponse(InputStream in) throws Exception{

    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line = null;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

 

4 Post请求

    Post请求在代码上与Get请求的主要区别是将HttpGet换成了HttpPost,其余部分代码基本一致。请看代码:

// (1) 创建HttpGet实例
HttpPost post = new HttpPost("http://www.126.com");

// (2) 使用HttpClient发送get请求,获得返回结果HttpResponse
HttpClient http = new DefaultHttpClient();
HttpResponse response = http.execute(post);

// (3) 读取返回结果
if (response.getStatusLine().getStatusCode() == 200) {
    HttpEntity entity = response.getEntity();

    InputStream in = entity.getContent();
    readResponse(in);
}

  

与Get请求不同的代码被标注为红色。可见Post请求与Get请求在代码上的区别并不大,互相切换也是比较容易的。在下面可以看到的令一个不同之处是传递的查询字符串,即请求参数。

 

5 参数传递

    Get与Post在传递参数时有一些区别,Get请求的参数作为查询字符串出传递,而Post请求的参数则作为实体传递。在开发WEB项目时经常遇到乱码的问题,使用HttpComponents也会涉及到这个问题,所以在使用时应特别注意。服务器端的处理方法与WEB项目相同, HttpComponents只要注意字符编码就可以了。

 

Get请求传递参数方法一:将查询字符串作为请求地址的一部分

这是一种最简单的传参方式,将查询参数用(&)连接,然后放在请求地址?的后面,如下面这个请求地址

 

http://localhost:8080/servlet1?name=ahopedog&work=programer

 

请看代码:

 

// (1) 创建HttpGet实例
HttpGet get = new HttpGet("http://localhost:8080/jsx/servlet?id=007");

 

这里只对请求地址稍作了些修改,请求地址是http://localhost:8080/jsx/servlet

查询参数是id=007

请求地址与查询参数之间用?连接

 

Get请求传递参数方法二:使用URI携带查询字符串

还记得上面提到的HttpGet有一种用URI构造的方法吗?这第二种传递的方式就是借助了这个机制,只是HttpComponents提供了一种创建查询参数比较清晰的方式NameValuePair

// (1)创建查询参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", "ahopedog"));
params.add(new BasicNameValuePair("work", "程序员"));
String queryString = URLEncodedUtils.format(params, "utf-8");

// (2) 创建Get实例
URI uri = URIUtils.createURI("http", "localhost", 8080, "/jsx/servlet", queryString, null);
HttpGet get = new HttpGet(uri);

  

(1)NameValuePair用一对键、值表示一个查询参数,将多个NameValuePair放在一个List中,就形成了一组查询参数。但是List<NameValuePair>并不能直接被HttpGet使用,所以需要用URLEncodedUtils.format()方法将其编码成字符串。URLEncodedUtils是HttpComponents提供的一个编译查询字符串的工具类。

(2)使用编译好的查询字符串构造URI对象,这样查询参数就一起被发送到了服务器上。

其实,这里的查询字符串完全可以手工的方式拼凑出来,只是,从代码的清晰性和维护性方面考虑,NameValuePair和URLEncodedUtils的方式更加可取。值得一提的是,在开发J2EE项目时,经常遇到一些查询条件或请求条件众多的情况,有的是将多个值放在一个Map中管理,有的则创建一个固定结构的Java Bean类。在这方面不同人可能会有不同的看法。Map方式固然省事,而且也很灵活,但是如果缺少了文档和注释时,会很难知道这个Map中放的到底是什么。而创建成Java Bean的话,代码本身就是一个很好的说明,让人一目了然,缺点是导致Java Bean的急剧增加,以致混乱和难以管理。

本人想不到什么很完美的解决办法,但是,任何极端的方式都是不可取,我想在这时折中或许稍好些,什么方法由场景决定。

Post请求传递参数:

// (1) Post请求
HttpPost post = new HttpPost("http://localhost:8080/jsx/servlet");

//添加参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", "ahopedog"));
params.add(new BasicNameValuePair("work", "程序员"));
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

// (3) 发送请求
HttpClient http = new DefaultHttpClient();
HttpResponse response = http.execute(post);

  

也是用到了List<NameValuePair>组织参数,这样就不用费更多心思研究新的方式了。将请求参数加入查询是上面代码中红色文字的一行。很简单,只要别把你的字符编码搞错就行了。

6 响应

直接操作响应中的输入流是最直接也是最有效的方式,不过需要注意的一点是,输入流读取完以后一定要将其关闭。

其实在前面的代码中已经涉及过了对响应的处理,这里再加详细的给予说明:

// (1) Post请求 
HttpPost post = new HttpPost("http://www.126.com"); 

// (2) 发送请求
HttpClient http = new DefaultHttpClient();
HttpResponse response = http.execute(post);

// (3) 处理响应结果
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();

// (4) 从输入流读取网页字符串内容
System.out.println(entity.getContentType());
System.out.println(entity.getContentEncoding());
System.out.println(entity.getContentLength());

InputStream in = null;
try{
in = entity.getContent();

BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
} 

}finally{
//记得关闭输入流
if(in != null)
in.close();
}

  


在本例中只需关心标记为红色的代码,其它行的代码上面已经介绍过了。

HttpEntity有3个获取返回数据的描述信息(或叫做元数据)

getContentType():获取响应体的类型

getContentEncoding():获取响应体的字符编码

getContentLength():获取响应体的字节长度

元数据的内容由远程服务器返回,实际上这些信息是包含在响应的头部信息中的,HTTP请求的响应头中还包含了其它有用的信息,HttpComponents将返回头中的关键元数据封装到了HttpEntity中,已便于使用。

entity.getContent()可以得到响应体的InputStream,有了这个流对象,基本上就可以"为所欲为"了。因为InputStream是Java I/O中底层的基础类,结合相对上层的输入流对象或者对字节进行编码等方法就可以获得不同类型和形式的响应数据了。在本例中用BufferedReader将响应体以字符串形式读取(返回的内容确实也是字符串的内容)。

 

7 headers

头部信息在客户端与服务器的HTTP传输过程中提供元数据,如服务器类型、处理时间、内容长度、内容类型等。

7.1 请求头部信息

下图是用Firefox访问Google时获取到的请求头信息,在我们使用浏览器访问一个网址时,浏览器都会默默的将一些与请求和客户端相关的信息发送给服务器,让服务器能更好的处理特定的客户端请求。这里面也包括了Cookie。

 

从上图中可以看到,在发送给服务器的头信息里,Host是我们访问的远程服务器主机地址。User-Agent是浏览器标识,服务器程序可以通过这个字符串得知客户端浏览器的类型和操作系统等信息。Accept-Charset则是客户端可以接受的字符编码类型。

其它各参数的含义在这里就不再一一说明了,感兴趣的读者可以参考相关文章或在Google上搜索相关的资料。

我们是使用HttpComponents代替浏览器访问服务器,默认情况并不包含浏览器所传递的头信息。即使不传递这些信息,通常服务器也会正常返回你所要的网页HTML内容的。但如果你真的很无聊,或者有一些特殊的操作,则完全可以模拟浏览给远程服务器发送这些头信息。

// (1) Post请求
HttpPost post = new HttpPost("http://www.126.com");

// (2) 添加请求头信息
post.setHeader("User-Agent", "Ahopedog/5.0 (Linux NT 5.1; rv:5.0) Gecko/20100101 FireDog/5.0");
post.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");

// (3) 发送请求
HttpClient http = new DefaultHttpClient();
http.execute(post);

  

上面两行红色代码向HttpPost中添加了User-Agent, Accept-Charset两个头信息(内容可以随意设置),头信息会随着HttpClient的execute一起发送出去。

7.2 响应头部信息

还是先在浏览器中都会得到什么样的响应头

 

上图内容是从FireBug返回头的截图,返回头包含了服务器时间,缓存控制,返回内容编码,服务器等信息。这里很有意思的一处是Google的服务器是gws,而百度的服务器则是BWS/1.0,从没见过的服务器,看来是自主研发的,不过名字也用不着太相近吧。

接下来,看看HttpComponents是如何解析这些信息的

// (1) Post请求 
HttpPost post = new HttpPost("http://www.126.com"); 

// (2) 发送请求
HttpClient http = new DefaultHttpClient();
HttpResponse response = http.execute(post);

// (3) 遍历返回头
Header[] headers = response.getAllHeaders(); 
for(Header h : headers){
System.out.println(h.getName() + " : " + h.getValue()); 
}
System.out.println("======================================");

// (4) 获取Server头信息,头名字不区分大小写
Header serverHeader = response.getFirstHeader("server");
System.out.println(serverHeader.getName() + " : " + serverHeader.getValue());

  

(3)response.getAllHeaders()得到响应头数组,一个响应头封装成一个Header实例。Header的两个关键方法是getName()和getValue(),得到头名字和值。

(4)response.getFirstHeader()可以指定获取一个特定的头,需要指定头的名字。多个头名字是可以重名的,而getFirstHeader是得到同名头中的第一个。

 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HttpComponents入门解析 的相关文章

  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • php oracle客户端oci8安装出现什么问题

    我尝试了安装 PHP Oracle 客户端的所有过程 1 我安装了客户端版本8和32位 2 我在php ini中取消了oci的注释 3 重新启动Wamp 4 不确定是否真的安装 但我在 php ini 中得到了引用 5 但仍然无法连接 泰汉
  • 当我使用 session_start() 时,Xampp 7.0.1 Apache 崩溃

    当我在 PHP 中使用 session start 启动会话时 我的 Apache 服务器停止工作 我正在使用 Windows 版 Xampp 7 0 1 我的配置文件如下所示 即使我把它放在文件的第一行 它也不起作用 有人知道如何解决这个
  • Paypal 将钱从一个帐户转移到另一个帐户

    我知道这个建议如何汇款至任何 PayPal 账户 https stackoverflow com questions 1559808 paypal api send money to any paypal account但到目前为止我所尝试
  • 无法理解 Java 地图条目集

    我正在看一个 java 刽子手游戏 https github com leleah EvilHangman blob master EvilHangman java https github com leleah EvilHangman b
  • 在具有相同属性名称的不同数据类型上使用 ModelMapper

    我有两节课说Animal AnimalDto我想用ModelMapper将 Entity 转换为 DTO 反之亦然 但是对于具有相似名称的一些属性 这些类应该具有不同的数据类型 我该如何实现这一目标 动物 java public class
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • 使用 Flyway 和 Hibernate 的 hbm2ddl 在应用程序的生命周期中管理数据库模式

    我正在开发 Spring Hibernate MySql 应用程序 该应用程序尚未投入生产 我目前使用 Hibernatehbm2ddl该功能对于管理域上的更改非常方便 我也打算用Flyway用于数据库迁移 在未来的某个时候 该应用程序将首
  • 如何在 Maven 中显示消息

    如何在 Maven 中显示消息 在ant中 我们确实有 echo 来显示消息 但是在maven中 我该怎么做呢 您可以使用 antrun 插件
  • 如何配置eclipse以保持这种代码格式?

    以下代码来自 playframework 2 0 的示例 Display the dashboard public static Result index return ok dashboard render Project findInv
  • 使用 MYSQL 将 h:mm pm/am 时间格式插入数据库

    我正在尝试将以 h mm am pm 格式写入的时间插入到存储为标准 DATETIME 格式 hh mm ss 的数据库中 但我不知道如何将发布的时间转换为标准格式所以数据库会接受它 这是我到目前为止一直在尝试的 title POST in
  • 将2-3-4树转换为红黑树

    我正在尝试将 2 3 4 树转换为 java 中的红黑树 但我无法弄清楚它 我将这两个基本类编写如下 以使问题简单明了 但不知道从这里到哪里去 public class TwoThreeFour
  • if/else 简写来定义变量

    我很难理解 if else 的 php 简写是如何描述的here https stackoverflow com questions 20233207 php if shorthand and echo in one line possib
  • 禁用 WooCommerce 手动/编辑订单的电子邮件通知

    需要 WooCommerce 专业知识 我需要禁用手动创建的订单的电子邮件通知 我必须使用处理状态 由于处理订单状态的自定义挂钩 我无法创建自定义状态 理想情况下 手动订单页面中可以勾选一个复选框 勾选后 它将禁止在每种状态下向客户发送电子
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • java8 Collectors.toMap() 限制?

    我正在尝试使用java8Collectors toMap on a Stream of ZipEntry 这可能不是最好的想法 因为在处理过程中可能会发生异常 但我想这应该是可能的 我现在收到一个我不明白的编译错误 我猜是类型推理引擎 这是
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item

随机推荐

  • 人工智能结构图

    人工智能结构图
  • PNP的学习-EPNP

    EPNP主要是利用已知的3d点 通过PCA选择4个控制点 建立新的局部坐标系 从而将3d坐标用新的控制点表示出来 然后 利用相机投影模型和2d点 转换到相机坐标系中 再在相机坐标系中建立和世界坐标系同样关系 每个点在相机坐标系和世界坐标系下
  • Composer 杂记

    帐号管理 config composer auth json Composer install 文件下载失败 重试好几次都失败 删除掉composer lock文件 重新 composer install 成功 使用国内的源 compose
  • [代码调试]SPHP代码调试误入的坑

    SPHP论文下载链接 今天在找SPHP论文的代码时 发现谷歌上有一位兄弟上传了 说是作者上传的源码 以为很快就可以将论文中的结果复现出来 却没想到折腾了一晚上毫无进展 下面我把我的错误经验分享给大家 SPHP代码下载链接 当我们下载完这个代
  • 编程实战(3)——python绘制极坐标雷达图

    编程实战 3 python绘制极坐标雷达图 文章目录 编程实战 3 python绘制极坐标雷达图 综述 绘图代码和解析 绘制一张多主体雷达图 预处理 封闭雷达图 绘制图像 绘制多张单主体雷达图 建立子图 循环遍历画每个子图 综述 pytho
  • java远程连接linux并发送命令,两种方案比较Jsch与ganymed-ssh2

    通过Jsch连接 step 1引入jar包
  • k8s之ReplicaSet

    我们在定义pod资源时 可以直接创建一个kind Pod类型的自主式pod 但是这存在一个问题 假如pod被删除了 那这个pod就不能自我恢复 就会彻底被删除 线上这种情况非常危险 所以今天就给大家讲解下pod的控制器 所谓控制器就是能够管
  • Log4cpp:为中小型C++项目加上log支持

    对于一个上点规模的C 项目而言 Log的作用是毋庸置疑的 出问题的时候 看了Log 常见的问题处理起来自是方便不过 即使遇到麻烦的问题 也可以从 总发现不少蛛丝马迹 因此一个严肃的项目应该从一开始就好好考虑如何打Log 便于分析 维护 现实
  • Selenium3自动化测试【6】浏览器driver的安装(FireFox)

    Selenium支持各种浏览器 读者可以在不同的浏览器中开展自动化测试 它支持的浏览器包括IE FireFox Chrome Opera Safari等 本讲就围绕常用的FireFox Chrome与Selenium的结合进行讲解 由于Se
  • 遥测终端机RTU助力城市内涝监测系统

    一 背景概述 2023年第5号台风 杜苏芮 周末登陆福建晋江 一波未平一波又起 卡努台风也进入了48小时警戒线 台风侵袭给城市基础设施和居民生活带来了严重的影响 后面第11号台风 海葵 号随之带来了更多城市内涝问题 且难以一下子解决 为了有
  • iOS 开发之CocoaPods常用第三方框架导入

    1 使用终端打开文件 假设项目放在桌面上 cd Desktop cd 项目名称 2 创建Podfile文件 命令如下 vim Podfile 3 输入 i 进入编辑模式并copy下面的这段代码 platform ios 8 0 target
  • C语言比较两个字符串是否相等的案例讲解

    思路分析 比较两个字符串是否相等要看两个字符串的长度和内容是否一样 如果长度和内容有一个不一样那么这两个字符串不相等 方法1 strcmp函数可以比较2个字符串的大小和内容是否一样 我们可以使用这个函数来进行判断 知识补充 strcmp函数
  • Node.js——回调函数及事件处理机制

    目录 回调函数 定义 理解 事件处理机制 补充 回调函数 定义 什么是回调函数呢 通俗的讲 将一个函数A作为参数传递给函数B 在函数B内对函数A进行调用 函数A就是回调函数 Node js 异步编程的直接体现就是回调 回调函数在完成任务后就
  • VM虚拟机安装Ubantu18.04【踩坑无数】【指路合集】

    写在前面 因为自己最近正在学习 作为一个小白 也遇到了很多问题 这里一起记录一下给大家遇到相同问题的指指路 其实内容多难倒也没有 跟着教程走也不会有什么难度 只希望能减少遇到同样问题的人search有效信息的来解决自己问题的时间 安装教程指
  • git warning: LF will be replaced by CRLF in package.json解决办法

    在修改了package json文件之后 使用git add 提交代码出现以下报错 warning LF will be replaced by CRLF in package json The file will have its ori
  • JVM线上故障排查的基本操作

    前言 线上经常会遇到各种各样的问题 CPU 飚高 内存溢出 频繁 GC 总的来说 基本上就是cpu 磁盘 内存以及网络等相关问题 所以进行排查时候尽量四个方面依次排查一遍 同时例如jstack jmap等工具也是不囿于一个方面的问题的 基本
  • [Python] 转贴:anaconda 下多版本Python 安装说明(win10)

    anaconda 下多版本Python 安装说明 转贴再补充 原帖见 https blog csdn net soloyuyang article details 75807425在原帖基础上补充了图 但是主要工作还是原帖的 win10系统
  • android 串口开发

    FT312D有参考
  • AD批量隐藏元件注释(Comment)

    步骤 1 右击元件注释在菜单中选中 Find Similar Objects 查找相似元件 2 在弹出来的菜单中 在Part comment 后面的下拉框中选择Same 即设定筛选条件为筛选所有相同comment的元件 然后点击OK 最后点
  • HttpComponents入门解析

    1 简介 超文本传输协议 http 是目前互联网上极其普遍的传输协议 它为构建功能丰富 绚丽多彩的网页提供了强大的支持 构建一个网站 通常无需直接操作http协议 目前流行的WEB框架已经透明的将这些底层功能封装的很好了 如常见的J2EE