一. 概述
大家对HttpUrlConnection这个类并不陌生,它处于java.net包下的,是JDK支持的。它主要用来服务器端发送Http请求。
我在用Spring Boot 2.x + webmagic + quartz 做开源爬虫项目【hotDog】https://github.com/raysonfang/hotDog,有一个小功能:需要获取网站的ico,并转换成PNG图片。这样,我们在获取网站信息的时候,同时可以获取网站图标,而不用手动去操作。
重复性的工作就交给程序自动实现。解放双手,让我们可以做更多有意义的事情
那么,在做这个功能的时候, 就需要获取到ico的链接地址,然后发送http请求获取到ico图片流,转换成PNG的图片保存。
具体功能的思路我后面会专门做一个复盘总结。这里就不赘述了。
在实现这个功能的过程中,有使用到HttpUrlConnection这个类,熟悉或不熟悉的朋友们可以继续往下看,有意想不到的,等着你。我曾经也以为这个很简单的,但这次的功能开发过程中,就真真切切地遇到问题了。下面就先讲一讲问题。
二.使用过程中遇到的问题
我们先看一个大家觉得没毛病的普遍写法:
try {
String url = "https://www.baidu.com/";
URL url = new URL(url);
//得到connection对象。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置请求方式
connection.setRequestMethod("GET");
//连接
connection.connect();
//得到响应码
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
//得到响应流
InputStream inputStream = connection.getInputStream();
//将响应流转换成字符串
String result = is2String(inputStream);//将流转换为字符串。
Log.d("kwwl","result============="+result);
}
} catch (Exception e) {
e.printStackTrace();
}
我在写的时候,也是按照上面的步骤来写的,但是结果就是向我抛出异常。
1. java.lang.IllegalStateException: Already connected
2. java.lang.IllegalStateException: connect in progress
我们找一下抛出异常的代码位置:
![](https://img.haomeiwen.com/i7253165/913e451dfdeef8f3.png)
![](https://img.haomeiwen.com/i7253165/87666a49eb5ee3e7.png)
我们可以看到,在设置方法名和设置请求头的时候,会判断是否有连接已经打开,如果有连接存在,则抛出异常,不能设置。
从这两个异常可以看出,应该是有连接已经存在,没有关闭导致的异常错误。
针对这两个问题,我也先在网上搜索了资料,但结果都没具体的解决方案,要不就是不用换成HttpClient等。
三. 如何解决上面的两个问题
1. 分析原因:
应该在开了连接以后,没有调用connection.disconnect()释放连接导致。
2. 解决问题:
- 在finally{}中释放httpUrlConnection的连接:connection.disconnect()
- 将connection.connect()的代码注释掉,这个方法可以不用,也能正常发送请求。我就是把这行代码注释掉以后,解决了上面出现的问题。
大家在看到第二个解决方案的时候,心中会有疑问,如果我把创建连接给注释掉,那么HttpUrlConnection又是在何时打开进行的连接操作呢?至于这个问题,我也跟踪调试了源码。发现执行到下面这行代码的时候,就已经发送了请求,也返回了响应结果。我的理解就是在程序中connection.connect() 是为了防止前面出现问题,所以在执行了一次。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
网友评论