- 浏览: 5160431 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
silence19841230:
先拿走看看
SpringBoot2.0开发WebSocket应用完整示例 -
wallimn:
masuweng 写道发下源码下载地址吧!三个相关文件打了个包 ...
SpringBoot2.0开发WebSocket应用完整示例 -
masuweng:
发下源码下载地址吧!
SpringBoot2.0开发WebSocket应用完整示例 -
masuweng:
SpringBoot2.0开发WebSocket应用完整示例 -
wallimn:
水淼火 写道你好,我使用以后,图标不显示,应该怎么引用呢,谢谢 ...
前端框架iviewui使用示例之菜单+多Tab页布局
最近忙于一个项目,了解下httpclient,在这里总结出来,和大家一起学习分享,希望各位朋友提出宝贵的意见。
首先介绍一下项目的背景:
目标:把国内一家保险公司的“WEB一账通”改成“WAP一账通”。
资源:客户不提供任何的webservice接口。
本项目中用到的第三方组件是apache的httpclient,一个非常强大的网页抓取工具(抓这个字用得可能不太好), 这里和大家
一起讨论下httpclient的一些常用用法和要注意的地方。
本文引用的资源列表:
httpclient入门: http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
httpclient证书导入:http://www.blogjava.net/happytian/archive/2006/12/22/89447.html
httpclient高级认识:http://laohuang.iteye.com/blog/55613
httpclient官方文档:http://hc.apache.org/httpcomponents-client/index.html
httpclient资源关闭:http://www.iteye.com/topic/234759
上面的文章写得很好,看完之后也就知道怎么用httpclient这个很好的工具了,但是在这里还是补充一些比较重要的东西,也是项目中经
常碰到的问题。
首先要注意的有以下几点:
1、httpclient连接后资源释放问题很重要,就跟我们用database connection要释放资源一样。
2、https网站采用ssl加密传输,证书导入要注意。
3、做这样的项目最好先了解下http协义,比如302,301,200,404返回代码的含义(这是最基本的),cookie,session的机制。
4、httpclient的redirect状态默认是自动的,这在很大程度上给开发者很大的方便(如一些授权获得cookie),但是有时要手动管理下,比如
有时会遇到CircularRedirectException异常,出现这样的情况是因为返回的头文件中location值指向之前重复(端口号可以不同)地址,导致可能会出现死
循环递归重定向,这时可以手动关闭:method.setFollowRedirects(false)
5、有的网站会先判别用户的请求是否是来自浏览器,如不是,则返回不正确的文本,所以用httpclient抓取信息时在头部加入如下信息:
header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
6、当post请求提交数据时要改变默认编码,不然的话提交上去的数据会出现乱码。重写postMethod的setContentCharSet()方法就可以了:
下面写一个通用类来处理request请求返回的文本:
首先介绍一下项目的背景:
目标:把国内一家保险公司的“WEB一账通”改成“WAP一账通”。
资源:客户不提供任何的webservice接口。
本项目中用到的第三方组件是apache的httpclient,一个非常强大的网页抓取工具(抓这个字用得可能不太好), 这里和大家
一起讨论下httpclient的一些常用用法和要注意的地方。
本文引用的资源列表:
httpclient入门: http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
httpclient证书导入:http://www.blogjava.net/happytian/archive/2006/12/22/89447.html
httpclient高级认识:http://laohuang.iteye.com/blog/55613
httpclient官方文档:http://hc.apache.org/httpcomponents-client/index.html
httpclient资源关闭:http://www.iteye.com/topic/234759
上面的文章写得很好,看完之后也就知道怎么用httpclient这个很好的工具了,但是在这里还是补充一些比较重要的东西,也是项目中经
常碰到的问题。
首先要注意的有以下几点:
1、httpclient连接后资源释放问题很重要,就跟我们用database connection要释放资源一样。
2、https网站采用ssl加密传输,证书导入要注意。
3、做这样的项目最好先了解下http协义,比如302,301,200,404返回代码的含义(这是最基本的),cookie,session的机制。
4、httpclient的redirect状态默认是自动的,这在很大程度上给开发者很大的方便(如一些授权获得cookie),但是有时要手动管理下,比如
有时会遇到CircularRedirectException异常,出现这样的情况是因为返回的头文件中location值指向之前重复(端口号可以不同)地址,导致可能会出现死
循环递归重定向,这时可以手动关闭:method.setFollowRedirects(false)
5、有的网站会先判别用户的请求是否是来自浏览器,如不是,则返回不正确的文本,所以用httpclient抓取信息时在头部加入如下信息:
header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
6、当post请求提交数据时要改变默认编码,不然的话提交上去的数据会出现乱码。重写postMethod的setContentCharSet()方法就可以了:
下面写一个通用类来处理request请求返回的文本:
/* * HttpRequestProxy.java * * Created on November 3, 2008, 9:53 AM */ package cn.com.mozat.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.SimpleHttpConnectionManager; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import cn.com.mozat.exception.CustomException; /** * * @author bird email:lihongfu-84@163.com * * 2008-11-4 09:49:48 */ public class HttpRequestProxy{ //超时间隔 private static int connectTimeOut = 60000; //让connectionmanager管理httpclientconnection时是否关闭连接 private static boolean alwaysClose = false; //返回数据编码格式 private String encoding = "UTF-8"; private final HttpClient client = new HttpClient(new SimpleHttpConnectionManager(alwaysClose)); public HttpClient getHttpClient(){ return client; } /** * 用法: * HttpRequestProxy hrp = new HttpRequestProxy(); * hrp.doRequest("http://www.163.com",null,null,"gbk"); * * @param url 请求的资源URL * @param postData POST请求时form表单封装的数据 没有时传null * @param header request请求时附带的头信息(header) 没有时传null * @param encoding response返回的信息编码格式 没有时传null * @return response返回的文本数据 * @throws CustomException */ public String doRequest(String url,Map postData,Map header,String encoding) throws CustomException{ String responseString = null; //头部请求信息 Header[] headers = null; if(header != null){ Set entrySet = header.entrySet(); int dataLength = entrySet.size(); headers= new Header[dataLength]; int i = 0; for(Iterator itor = entrySet.iterator();itor.hasNext();){ Map.Entry entry = (Map.Entry)itor.next(); headers[i++] = new Header(entry.getKey().toString(),entry.getValue().toString()); } } //post方式 if(postData!=null){ PostMethod postRequest = new PostMethod(url.trim()); if(headers != null){ for(int i = 0;i < headers.length;i++){ postRequest.setRequestHeader(headers[i]); } } Set entrySet = postData.entrySet(); int dataLength = entrySet.size(); NameValuePair[] params = new NameValuePair[dataLength]; int i = 0; for(Iterator itor = entrySet.iterator();itor.hasNext();){ Map.Entry entry = (Map.Entry)itor.next(); params[i++] = new NameValuePair(entry.getKey().toString(),entry.getValue().toString()); } postRequest.setRequestBody(params); try { responseString = this.executeMethod(postRequest,encoding); } catch (CustomException e) { throw e; } finally{ postRequest.releaseConnection(); } } //get方式 if(postData == null){ GetMethod getRequest = new GetMethod(url.trim()); if(headers != null){ for(int i = 0;i < headers.length;i++){ getRequest.setRequestHeader(headers[i]); } } try { responseString = this.executeMethod(getRequest,encoding); } catch (CustomException e) { e.printStackTrace(); throw e; }finally{ getRequest.releaseConnection(); } } return responseString; } private String executeMethod(HttpMethod request, String encoding) throws CustomException{ String responseContent = null; InputStream responseStream = null; BufferedReader rd = null; try { this.getHttpClient().executeMethod(request); if(encoding != null){ responseStream = request.getResponseBodyAsStream(); rd = new BufferedReader(new InputStreamReader(responseStream, encoding)); String tempLine = rd.readLine(); StringBuffer tempStr = new StringBuffer(); String crlf=System.getProperty("line.separator"); while (tempLine != null) { tempStr.append(tempLine); tempStr.append(crlf); tempLine = rd.readLine(); } responseContent = tempStr.toString(); }else responseContent = request.getResponseBodyAsString(); Header locationHeader = request.getResponseHeader("location"); //返回代码为302,301时,表示页面己经重定向,则重新请求location的url,这在 //一些登录授权取cookie时很重要 if (locationHeader != null) { String redirectUrl = locationHeader.getValue(); this.doRequest(redirectUrl, null, null,null); } } catch (HttpException e) { throw new CustomException(e.getMessage()); } catch (IOException e) { throw new CustomException(e.getMessage()); } finally{ if(rd != null) try { rd.close(); } catch (IOException e) { throw new CustomException(e.getMessage()); } if(responseStream != null) try { responseStream.close(); } catch (IOException e) { throw new CustomException(e.getMessage()); } } return responseContent; } /** * 特殊请求数据,这样的请求往往会出现redirect本身而出现递归死循环重定向 * 所以单独写成一个请求方法 * 比如现在请求的url为:http://localhost:8080/demo/index.jsp * 返回代码为302 头部信息中location值为:http://localhost:8083/demo/index.jsp * 这时httpclient认为进入递归死循环重定向,抛出CircularRedirectException异常 * @param url * @return * @throws CustomException */ public String doSpecialRequest(String url,int count,String encoding) throws CustomException{ String str = null; InputStream responseStream = null; BufferedReader rd = null; GetMethod getRequest = new GetMethod(url); //关闭httpclient自动重定向动能 getRequest.setFollowRedirects(false); try { this.client.executeMethod(getRequest); Header header = getRequest.getResponseHeader("location"); if(header!= null){ //请求重定向后的URL,count同时加1 this.doSpecialRequest(header.getValue(),count+1, encoding); } //这里用count作为标志位,当count为0时才返回请求的URL文本, //这样就可以忽略所有的递归重定向时返回文本流操作,提高性能 if(count == 0){ getRequest = new GetMethod(url); getRequest.setFollowRedirects(false); this.client.executeMethod(getRequest); responseStream = getRequest.getResponseBodyAsStream(); rd = new BufferedReader(new InputStreamReader(responseStream, encoding)); String tempLine = rd.readLine(); StringBuffer tempStr = new StringBuffer(); String crlf=System.getProperty("line.separator"); while (tempLine != null) { tempStr.append(tempLine); tempStr.append(crlf); tempLine = rd.readLine(); } str = tempStr.toString(); } } catch (HttpException e) { throw new CustomException(e.getMessage()); } catch (IOException e) { throw new CustomException(e.getMessage()); } finally{ getRequest.releaseConnection(); if(rd !=null) try { rd.close(); } catch (IOException e) { throw new CustomException(e.getMessage()); } if(responseStream !=null) try { responseStream.close(); } catch (IOException e) { throw new CustomException(e.getMessage()); } } return str; } public static void main(String[] args) throws Exception{ HttpRequestProxy hrp = new HttpRequestProxy(); Map header = new HashMap(); header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)"); String str = hrp.doRequest( "http://www.cma-cgm.com/en/eBusiness/Tracking/Default.aspx?BolNumber=GZ2108827", null, header,null); System.out.println(str.contains("row_CRXU1587647")); // System.out.println(str); } }
发表评论
-
gradle编译错误:Could not find method compile() for arguments
2020-09-19 10:50 18500编译(IDEA+Gradle)一个别人的工程,出现一个 ... -
netty心跳检查之UDP篇
2019-09-15 08:50 2393部分UDP通信场景中,需要客户端定期发送心跳信息,以获取终 ... -
解决tomcat部署两个SpringBoot应用提示InstanceAlreadyExistsException
2019-06-30 11:49 3388两个SpringBoot应用部署在一个Tomcat中,单独 ... -
Eclipse配置MyBatis代码自动化功能
2019-06-29 10:16 17701.安装插件 Eclipse中,Help->Ecli ... -
vue.js中使用qrcode生成二维码
2019-05-20 00:00 7654一、安装包 npm install qrcodejs2 --s ... -
MySQL插入数据报错: Incorrect string value: '\xFD\xDE'
2019-03-31 23:19 1251我MySQL数据库用的uft-8字符集,插入数据一直很正常 ... -
vue自定义组件并双向绑定属性
2019-03-08 22:46 3258做了两个子组件,原理基本一样,一个是使用原生的select ... -
vue-router简单示例
2019-03-05 00:32 1152写个基本完整、稍有借鉴意义的示例,防止自己忘记。 &l ... -
“联通充值系统繁忙”轻松应对
2019-02-06 11:03 3973大过年的,联通充个值一直报“充值系统繁忙”。昨天晚上试了几 ... -
electron.js数据库应用---导航菜单(element-ui+mysql)
2019-02-05 21:33 2364一、环境搭建 略, ... -
electron.js数据库应用---入门(mysql+element-ui)
2019-01-27 23:19 7496我的机器:Windows10,64 ... -
SpringMVC 在controller层中注入成员变量request,是否线程安全
2018-12-17 21:17 2748@RestController public class ... -
VueJS 组件参数名命名与组件属性转化
2018-12-03 00:00 2075转自:https://www.cnblogs.com/meiy ... -
vue-resource拦截器实现token发送及检验自动化
2018-11-16 22:38 3077用了很长时间vue-resource,最近思考$http发 ... -
element-ui试用手记
2018-10-29 20:25 1745element-ui、iviewui都以vue.js为基础 ... -
iviewui中表格控件中render的使用示例
2018-07-07 16:46 9786示例了如何在表格中显示按钮,如何将代码转化为文字。 i ... -
Tomcat错误“Alias name tomcat does not identify a key entry”解决
2018-07-05 21:39 6571申请到了阿里云的证书后,下载、按照说明生成jks格式证书、 ... -
阿里云免费证书“fileauth.txt内容配置错误”解决
2018-07-05 20:43 5299最近研究微信小程序开发,上阿里云申请了个证书,使用文件验证 ... -
springboot2.0跨域配置
2018-07-04 22:11 5285springboot2.0跨域配置: 一、代码 ... -
微信小程序使用code换openid的方法(JAVA、SpringBoot)
2018-07-01 21:52 10398微信小程序序的代码中提示,使用code换取openid,但 ...
相关推荐
### XML-RPC学习心得 #### 一、XML-RPC简介 XML-RPC(XML Remote Procedure Call)是一种轻量级的远程过程调用协议,它使用XML来编码调用数据,并通过HTTP进行传输。XML-RPC使得运行在不同操作系统上的应用程序...
以下是一些关于 HttpClient 4.5 的重要知识点: 1. **HttpClient 创建与配置**: HttpClient 4.5 提供了 `HttpClients.createDefault()` 方法,用于创建默认的、可关闭的 HTTP 客户端实例。全局使用一个客户端可以...
### Java学习心得与关键技术知识点详解 #### 一、Java程序执行环境 - **Java程序运行原理**:不论是Android应用、Web应用还是企业级Java Bean (EJB),所有的Java程序都是在一个独立的进程中运行的。每个Java应用都...
3. **互动社区**:集成论坛或聊天功能,鼓励用户之间交流学习心得,解答疑问,营造良好的学习氛围。 4. **个性化推荐**:通过算法分析用户的学习习惯和偏好,推送相关的学习内容,提高学习效率。 5. **实时更新与...
描述提到这是一份作者个人的Java API学习总结,愿意与网络上的朋友们共享,显示出这是一份个人经验的汇集,可能包含了作者在Java编程学习过程中的心得和实用代码示例。 标签“f79”和“java编程”进一步确认了这是...
描述中的链接指向了博主ihuning在iteye博客上的一篇具体文章,虽然描述部分是空的,但我们可以推测这篇文章可能详细介绍了作者在学习和使用HTTPComponents过程中的一些经验和心得,可能涵盖了如何设置请求、处理响应...
这份"我的Java学习笔记"详细记录了作者在学习Java过程中积累的心得体会和关键知识点,分为十章进行深入讲解。 1. **基本概念** - Java的起源和发展:了解Java的历史背景,创始人,以及它如何成为一种跨平台的编程...
在本文中,我们将深入探讨如何在Silverlight 2应用程序中实现跨域调用Web服务。首先,理解跨域调用的背景非常重要。由于浏览器的安全策略,JavaScript和由此产生的技术(如Silverlight)默认禁止跨域请求,以防止...
using (var client = new HttpClient()) { var content = await client.GetStringAsync(url); return content; } } ``` 通过以上知识点的学习,你将对C#有一个全面的了解,并能开始编写基本的C#程序。不过,...
2. **数据截获链接**: "开心农场制作心得——提供一些自己截获的链接.txt"可能包含游戏服务器请求的实际URL和参数,这有助于理解游戏的API调用和数据格式,例如作物的生长状态、用户信息、农场等级等。 3. **POST...
这份"java软件开发——顶岗实习周记25篇.pdf"文档,很可能是某个学生或初入职场的开发者在Java实习期间所记录的工作与学习心得,提供了宝贵的实战经验与反思。 首先,Java作为全球最流行的编程语言之一,其语法严谨...
JavaNote是一份全面的Java学习资源,包含了作者在学习Java编程过程中积累的笔记与心得。这份资料对于初学者和有一定经验的开发者来说都是一个宝贵的参考资料,可以帮助深化对Java语言的理解,提升编程技能。 1. **...
这个程序可能使用了常见的编程语言如Java、C#或Python实现,并且可能依赖了一些开源库或框架,如Apache HttpClient进行网络请求,或者使用 Pillow 或 OpenCV 处理图像。 在实际开发中,处理图像上传需要关注以下几...
CSDN(China Software Developer Network)是中国最大的IT技术社区,许多开发者在此分享他们的技术文章和学习心得。CSDN博客提供了一个方便的在线发布和管理个人博客的平台,但原始数据可能不易于其他地方使用或编辑...
对于“2000java包”这个压缩包,可能包含了2000个不同的Java相关的类库,涵盖了各种功能,学习和掌握这些库将对提升开发能力大有裨益。然而,实际的使用应根据项目需求选择合适的jar包,避免引入不必要的依赖,从而...
在“note”部分的学习笔记中,可能包含了对以上知识点的解释、示例代码和实践心得。而在“code”部分的DEMO中,作者可能编写了各种示例代码,涵盖了实际操作和应用场景,这对于初学者理解Java编程和进阶学习都非常有...
5. **讨论交流**:与其他开发者交流,分享学习心得,共同探讨解决方案,提升技术水平。 总之,这个"高仿精仿UC浏览器应用"的Java源码项目是一个绝佳的学习资源,它涵盖了移动应用开发的多个关键领域,对于提升Java...
《Android图书书架源码详解》 在移动设备上,Android操作系统以其开源、灵活的特点深受开发者喜爱。...通过分析这个源码,开发者不仅能学习到Android开发的基础知识,还能深入了解如何构建一个实用的图书管理应用。
【描述】:这个资料集合是作者在深入学习和实践Java编程过程中积累的心得体会,旨在帮助读者理解和掌握Java语言的核心概念、语法特性以及实际应用技巧。不仅如此,由于编程是一个广泛的领域,所以这个笔记也可能包括...
这个应用可以帮助用户创建、编辑、查看和分享他们的烹饪心得,从而打造一个互动的美食社区。 **1. Node.js与Express** Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者能够在服务器端使用 ...