浅析中文环境下的Apach Commons HttpClient编程

来源 :电脑知识与技术·学术交流 | 被引量 : 0次 | 上传用户:wangcwfq3
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:本文详尽的分析了在中文环境下运用Apach Commons HttpClient进行编程时出现的几个常见问题。针对每个问题,本文均给出较为完善的解决方案,对中文环境下的Apach Commons HttpClient编程具有极大的现实参考价值。
  关键词:Apach Commons HttpClient、程序设计、中文操作系统
  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)22-782-02
  Analyses of Apach Commons HttpClient Programming in Chinese OS Platform
  HONG Liang,TIAN Zhi-bin
  (Hunan Normal University, Changsha 410081, China)
  Abstract: The paper describes some common problems with Apach Commons HttpClient programming in Chinese OS platform. To every problem,the paper gives preferable solution which may be helpful to Apach Commons HttpClient programming.
  Key words: apach commons HttpClient; programming; Chinese OS platform
  1 Commons HttpClient开源项目简介
  Http协议是一种应用十分广泛的网络应用层协议。在Java网络编程中我们会经常碰到Http协议编程,虽然JDK提供了HttpURLConnection编程接口对Http协议进行支持,但是由于协议应用本身的复杂性,使得在大量实际项目单纯使用JDK进行Http编程仍然相对比较困难。针对这种情况,开源软件组织Apach推出了HttpClient开源组件,并且提供稳定持续的升级版本,因此在实际项目中采用HttpClient组件进行Http协议编程是一种高效经济的解决方案。
  2 Commons HttpClient中文环境下编程常见问题
  由于HttpClient组件设计的高度灵活性及易用性,应用HttpClient组件进行编程本身并不复杂。但是由于Java编程环境自身容易出现字符编码问题,衍生于Java语言并主要由英语语系国家技术人员推出的HttpClient组件自然在中文环境中会存在一定的编码问题,同时由于部分Web浏览器及Web服务器并未严格实现标准Http协议规范,使得比较严格遵循标准Http协议规范的HttpClient组件在与部分浏览器及服务器进行交互时会出现少量兼容性问题。笔者在中文环境下用HttpClinet开发校外资源访问系统的过程中碰到系列HttpClient技术问题,经过测试查证找到相应的解决办法,这对解决HttpClient编程问题,特别是中文环境下HttpClient编程具有较大的借鉴作用。(注:本文编程的HttpClient组件版本为:Release 3.1 Beta 1)
  3 Commons HttpClient编程的典型问题及解决办法
  3.1 URL中文参数无法识别的问题
  通常情况在Commons HttpClient编程中我们用下列语句就可以向一个目标服务器提交一个Web请求:
  HttpClient client=new HttpClient();
  GetMethod method = new GetMethod(url);//本示例使用Get方法,当然也可使用Post方法PostMethod method//=new PostMethod(url);
  client.executeMethod(method);
  InputStream receiver=method.getResponseBodyAsStream();
  如果URL没有中文参数,以上语句执行起来没有任何问题,但是如果URL中含有中文字符,中文参数将无法被Web服务器识别,程序虽然可以正常运行,但却无法得到正确结果。同时返回的Http响应头,如果含有中文字符也将出现乱码。分析源码发现,这是HttpClient中的HttpElementCharset参数(创建HTTP headers的字符集)的默认值为US-ASCII,ContentCharset参数(创建content body的字符集)的默认值为ISO-8859-1的原故,因此需要使用下列语句改变这些参数的默认值:
  client = new HttpClient();
  params=client.getParams();
  params.setHttpElementCharset("GBK");
  params.setContentCharset("GBK");
  或者使用:
  method.getParams().setHttpElementCharset("GBK");
  method.getParams().setCredentialCharset("GBK");
  method.getParams().setContentCharset("GBK");
  第一种方式可能会更好,它在HttpClient初始化时就对字符默认参数进行了设置,作用范围更广。第二种方式仅对使用具体的请求方法时起作用,字符集的作用范围有限。一般情况下我们用上述语句即可实现中文字符的正确识别。但要深入使用我们会发现如果URL中文参数含有中文特殊字符(如“{”,“}”等符号),程序将抛出URIException异常,导致请求无法完成。继续研究HttpClient的源代码发现,URI类是负责解析URL的核心类,控制URL编码字符集是ProtocolCharset参数,默认情况下为UTF-8编码,同时还在URI的构造函数提供了一个逻辑值来决定是否过滤非法字符,而恰恰一些中文特殊字符也被当成非法的字符过滤掉了,根据产生问题的原因,我们在基本解决中文编码问题的基础上结合以下容错的方法来最终保证中文编码的正确识别:
  String url=….;
  try
   {strUri=new URI(uri,true,"GBK");}
  catch(URIException e)
   {strUri=new URI(uri,false,"GBK");}
  method.setURI(strUri);
  经测试上述办法解决大量的已知URL中文参数不能识别的问题,当然如果在程序个别地方上述方法依然不能奏效,你还可以使用Java中文编码转换的基础解决方法,借助ISO-8859-1标准编码过渡,能够轻易将JVM在网络传送过程转换成的UTF8编码还原成GBK编码,下面的代码实现了这一功能:
  byte [] b;
  String utf8_value;
  utf8_value = request.getParameter("NAME");//从HTTP流中取"NAME"的UTF8数据
  b = utf8_value.getBytes("8859_1"); //中间用ISO-8859-1过渡
  String name = new String(b, "GB2312"); //转换成GB2312字符
  3.2 URL中的%问题
  部分不太规范的中文网站中使用%作URL中参数的一部分传递给服务器,而中文Windows中的许多主流浏览器也兼容这一例外。事实上%是作为Http协议中的UrlEncode编码的保留字符不能直接在URL中使用,必须被转义成%这样的形式,事实上HttpClient就会自动将字符%转化成%。正是这种原因当HttpClient截获IE浏览器的请求并将其转发到服务器时,将会导致查询参数错误。分析HttpClient的源码发现,这一转化是在URI类中实现的,经反复测试未能找到一种通过HttpClient公开接口实现这一兼容性的方法。目前只能采取修改URI类源码重新编译的办法来实现:
  public static final BitSet allowed_query = new BitSet(256);
  // Static initializer for allowed_query
  static {
  allowed_query.or(uric);
  allowed_query.clear(’%’);将源码中此语句去掉或注释即可}
  3.3 Cookie整合问题
  IE和Firefox在发送请求给服务器时会把所有的cookie打包成一个,然后在这个cookie里按照分号把每一项隔开,中间有个空格。但httpclient会在header里构建多个cookie项,每一项只含有一个cookie,这同IE是不一样的。为了使用IE这种发送方式,我们需要设置一个请求方法中的一个Cookie参数,参考设置如下:
  method.getParams().setParameter(HttpMethodParams.SINGLE_COOKIE_HEADER,new Boolean(true)); //使多个cookie合并成一个cookie头
  3.4 chunked编码不规范的问题
  有时候Web服务器生成HTTP Response是无法在Header就确定消息大小的,这时一般来说服务器将不会提供Content-Length的头信息,而采用Chunked编码动态的提供body内容的长度。 Chunked编码使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束。使用十分广泛的Tomcat Web服务器大量采用了Chunked编码方案,然而早期的Tomcat Web服务器实现并不十分规范,并没有以标明长度为0的chunk标示内容传输结束。因此HttpClient在接收这些早期的Tomcat Web服务器的Http响就会导致解析错误。分析HttpClient源码发现,ChunkedInputStream类负责在HttpClient中解析chunked编码,修改一个此类中getChunkSizeFromInputStream(final InputStream in)方法,可使标准的和上述非标准的chunked编码均可正常解析。具体修改方法如下:
  private static int getChunkSizeFromInputStream(final InputStream in)
  throws IOException {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  // States: 0=normal, 1=\r was scanned, 2=inside quoted string, -1=end
  int state = 0;
  while (state != -1) {
  int b = in.read();
  if (b == -1) {
  return 0;//新增加语句
  throw new IOException("chunked stream ended unexpectedly");//原始语句,需将其去掉或注释掉}
  3.5 Host头无法修改的问题
  HttpClient本身在HttpMethodBase类中提供增加和修改Http请求头的addRequestHeader和setRequestHeader方法,然而却无法修改Host参数,而在一此特殊的场合又要求修改这一参数。经分析源码发现,HttpClient在设置Http请求头设计成了不能修改的固定模式。因此为适应特殊要求,只能修改和重编译HttpMethodBase类。具体修改方法如下:
  protected void addRequestHeaders(HttpState state, HttpConnection conn)
  throws IOException, HttpException {
  LOG.trace("enter HttpMethodBase.addRequestHeaders(HttpState, "
   "HttpConnection)");
  
  addUserAgentRequestHeader(state, conn);
  addHostRequestHeader(state, conn); //原始语句,需将其去掉或注释掉
  addCookieRequestHeader(state, conn);
  addProxyConnectionHeader(state, conn);}
  参考文献:
  [1] Hypertext Transfer Protocol-HTTP/1.1[S/OL].RFC2068.1997-01.http://jakarta.apache.orglcommons/http-client/userguide.html.
  [2] Apache Jakarta Common HttpClient[EB/OL].(2004-03).http://jakarta.apache.org/commons/httpclient/userguide.html.
  [3] Apach Commons HttpClient [EB/OL].(2007-02).http://jakarta.apache.org/commons/httpclient
  [4] HttpClient入门[EB/OL].(2006-12).http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
  [5] Harold E R,著.Java网络编程[M].朱涛江,林剑,译.北京:中国电力出版社,2005.
其他文献
摘要:介绍OLAP技术在税收数据分析中的应用,为税务管理部门提供辅助决策功能。  关键词: 税务数据分析;OLAP技术  中图分类号:TP399文献标志码:A 文章编号:1009-3044(2008)26-1622-01  The Application of OLAP Technology For Tax Data Analysis  LV Jia   (School of Computer S
【关键词】深度学习,闭环思维,教学视角  学生的实际学习情况存在较大差异,但在现有的语文课堂上往往被忽略,教师让学生按照同样的方式、进度进行学习。学生在学习过程中没有主动提问的意识,没有探索问题的过程,没有深入思考的能力,学习就成了一件缺少意义的机械运动。这种情况下,深度学习作为一种关注学生深层理解,引发学生主动学习愿望,促进学生全面发展的学习方式,就成为撬动课堂的主要突破口和发力点。学生如何实现
近年来,中华优秀传统文化在国家文化战略中的地位不断加强,课程、教材需要承担的责任不断被强化。2006年《国家“十一五”时期文化发展规划纲要》明确指出,要加強传统文化教育,“坚持继承和弘扬优秀民族文化传统,吸收和借鉴世界各国优秀文化成果”。2014年教育部印发的《完善中华优秀传统文化教育指导纲要》中指出,要把中华优秀传统文化教育系统融入课程和教材体系,分学段有序推进中华优秀传统文化教育——明确提出了
摘要:目前,我国很多高校都开设了《Java语言程序设计》,其教学效果直接影响学生的程序设计能力。文章就Java语言教学过程中的教学内容、教学方法、实验教学等方面进行探讨,并总结了一些教学上的经验和体会。  关键词:Java;面向对象;教学方法  中图分类号:G642文献标识码:A文章编号:1009-3044(2008)19-30109-02  Research and Practice on th
新课程改革后,批判性思维愈发受到语文学界的重视,并成为在当前基于核心素养的课程改革中的热点研究课题。而学科教学无疑是培养学生批判性思维的最重要的途径。那么,如何在教学中培养学生的批判性思维能力?怎样才能创新性地让学生正确理解和掌握批判性思維?在参与“批判性思维素养培养模型融入语文教学的实证研究”课题时,笔者研读了布鲁克·诺埃尔·摩尔和理查德·帕克合著的《批判性思维》一书。可以说,这本书很好地回答了
进入21世纪以来,新科技手段层出不穷,人类逐渐从图文信息时代步入“微时代”。在此背景下,高校思想政治教育从理论到实践将发生一系列新的变化。《微时代背景下高校思想政治教育理论及实践研究》一书立足当前时代背景,深入研究高校思想政治教育遇到的新问题,对于丰富大学生思想政治教育的实践途径、增强高校思想政治教育的实效性有很大帮助。  大学生群体自身的特质使其更容易融入“微时代”,也由此带来多方面的影响,有积
镜泉先生,以镜为鉴,以泉濯心,得以进全,是故为名。  初识镜泉先生于陋屋,一杯素茶,三尺画台,九尺画布,百幅画稿,书无杂尘,座无旁人,沉浸在山水中,游山戏水弄熊猫,怡然稍作寒暄,镜泉先生爽朗宏亮的声音便将我们带入到了他的生活,进而得知,镜泉先生本名刘进全。  镜泉先生学画四十余载,首先着力于写意山水画的创作,从开始实实在在的用笔,不断的复加和重叠渲染出真实的自然之美,到后来,先生把自己对大自然的感
摘要:服务器是在网络上为用户提供服务和资源的计算机。笔者从定义、功能服务等方面区别分析Web服务器与应用程序服务器的不同之处,为大家在学习服务器相关知识时提供借鉴和参考。  关键词:Web服务器;应用程序服务器  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)24-1139-01  The Different of Web Server and Application
摘要:子网掩码在网络通信中具有非常重要的作用。通过分析网络测试中常用的Ping命令所反馈的不同结果与子网掩码的关系,判断网络故障原因,进行网络定位,帮助用户深入理解子网掩码。对常见网络故障的分析、排除具有重要意义。  关键词:ping;子网掩码;网络故障  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)27-1895-02  A Diagnosis Method of
摘要:为提高师范生信息素养,该文提出了基于Big 6的培养模式。实践证明:在《多媒体课件制作》课程中运用Big 6教学模式,学生对学习任务的兴趣增强了,分析问题、解决问题的能力提高了,对信息的搜索、筛选、整合的能力也得到了一定的锻炼,对提高信息素养取得了明显的成效。  关键词:高师生;信息素养;信息素养教育;Big 6  中图分类号:TP37文献标识码:A文章编号:1009-3044(2008)2