`
jsx112
  • 浏览: 315314 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HttpClient 学习整理

阅读更多
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的应用可以参见http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 项目非常活跃,使用的人还是非常多的。
Commons-httpclient是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决,例如你不再管是HTTP或者HTTPS的通讯方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。
下面以几个小例子来说明httpclient的使用方法
1、使用get或post方法获得远程的url地址的网页内容
public class SimpleClient {
public static void main(String[] args) throws IOException {
HttpClient client = new HttpClient();
// 设置代理服务器地址和端口

// client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
// 使用 GET 方法 ,如果服务器需要通过 HTTPS 连接,那只需要将下面 URL 中的 http 换成 https
HttpMethod method = new GetMethod("http://www.baidu.com");
// 使用POST方法
//HttpMethod method = new PostMethod("http://www.baidu.com");
client.executeMethod(method);

// 打印服务器返回的状态
System.out.println(method.getStatusLine());
// 打印返回的信息
System.out.println(method.getResponseBodyAsString());
// 释放连接
method.releaseConnection();
}
}
2、以GET或者POST方式向网页提交参数
public String postMethod(boolean needAuth,String InterBiz ,String userName,String password,String picPath, String msg) throws HttpException, IOException{
HttpClient client = new HttpClient();
// client.getHostConfiguration().setHost("api.minicloud.com.cn", 80,"http");
PostMethod method = new PostMethod(InterBiz);
MultipartRequestEntity mrp=null;
if (needAuth) {
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT,AuthScope.ANY_REALM),
new UsernamePasswordCredentials(userName, password));
method.setDoAuthentication(true);
}
msg = URLEncoder.encode(msg, "UTF-8");
StringPart sp = new StringPart("status", msg);

if(picPath==null|| picPath.trim().equals("")){
mrp = new MultipartRequestEntity(new Part[] {sp }, method.getParams());
}else{
File file = new File(picPath);
FilePart fp = new FilePart("pic", file.getName(), file,
new MimetypesFileTypeMap().getContentType(file), "UTF-8");
fp.setTransferEncoding("binary");
mrp = new MultipartRequestEntity(new Part[] {
sp,fp}, method.getParams());
}
method.setParameter("status", msg);
method.setRequestEntity(mrp);
client.executeMethod(method);
String jsonData=new String(method.getResponseBodyAsString().getBytes("gbk"));
method.releaseConnection();
return jsonData;
}
3. 处理页面重定向

在JSP/Servlet编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跳转,也就是说应用容器加载了所要跳转的页面的内容并返回给客户端;而前者是返回一个状态码,这些状态码的可能值见下表,然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程,所以我们编程的时候就要通过HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了,那么可以通过读取HTTP头中的location属性来获取新的地址。

状态码
对应 HttpServletResponse 的常量
详细描述

301
SC_MOVED_PERMANENTLY
页面已经永久移到另外一个新地址

302
SC_MOVED_TEMPORARILY
页面暂时移动到另外一个新的地址

303
SC_SEE_OTHER
客户端请求的地址必须通过另外的 URL 来访问

307
SC_TEMPORARY_REDIRECT
同 SC_MOVED_TEMPORARILY



下面的代码片段演示如何处理页面的重定向

client.executeMethod(post);
System.out.println(post.getStatusLine().toString());
post.releaseConnection();
// 检查是否重定向
int statuscode = post.getStatusCode();
if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) || (statuscode == HttpStatus.SC_SEE_OTHER) || (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
// 读取新的 URL 地址
   Headerheader=post.getResponseHeader("location");
   if (header!=null){
      Stringnewuri=header.getValue();
      if((newuri==null)||(newuri.equals("")))
         newuri="/";
         GetMethodredirect=newGetMethod(newuri);
         client.executeMethod(redirect);
         System.out.println("Redirect:"+redirect.getStatusLine().toString());
         redirect.releaseConnection();
   }else
    System.out.println("Invalid redirect");
}

我们可以自行编写两个JSP页面,其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。

4. 模拟输入用户名和口令进行登录

本小节应该说是HTTP客户端编程中最常碰见的问题,很多网站的内容都只是对注册用户可见的,这种情况下就必须要求使用正确的用户名和口令登录成功后,方可浏览到想要的页面。因为HTTP协议是无状态的,也就是连接的有效期只限于当前请求,请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必须使用到Cookie机制。以JSP/Servlet为例,当浏览器请求一个JSP或者是Servlet的页面时,应用服务器会返回一个参数,名为jsessionid(因不同应用服务器而异),值是一个较长的唯一字符串的Cookie,这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问该站点的其他页面时候都要带上jsessionid这样的Cookie信息,应用服务器根据读取这个会话标识来获取对应的会话信息。

对于需要用户登录的网站,一般在用户登录成功后会将用户资料保存在服务器的会话中,这样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息,然后就可以判断用户资料是否存在于会话信息中,如果存在则允许访问页面,否则跳转到登录页面中要求用户输入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。

这样一来,对于HTTP的客户端来讲,如果要访问一个受保护的页面时就必须模拟浏览器所做的工作,首先就是请求登录页面,然后读取Cookie值;再次请求登录页面并加入登录页所需的每个参数;最后就是请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多,可是如果你使用httpclient的话,你甚至连一行代码都无需增加,你只需要先传递登录信息执行登录过程,然后直接访问想要的页面,跟访问一个普通的页面没有任何区别,因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实现了这样一个访问的过程。


/*
* Created on 2003-12-7 by Liudong
*/

package http.demo;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.*;
import org.apache.commons.httpclient.methods.*;

/**
* 用来演示登录表单的示例
* @author Liudong
*/

public class FormLoginDemo {
   static final String LOGON_SITE = "localhost" ;
   static final int     LOGON_PORT = 8080;

   public static void main(String[] args) throws Exception{
      HttpClient client = new HttpClient();
      client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);

      // 模拟登录页面 login.jsp->main.jsp
      PostMethod post = new PostMethod( "/main.jsp" );
      NameValuePair name = new NameValuePair( "name" , "ld" );
      NameValuePair pass = new NameValuePair( "password" , "ld" );
      post.setRequestBody( new NameValuePair[]{name,pass});
      int status = client.executeMethod(post);
      System.out.println(post.getResponseBodyAsString());
      post.releaseConnection();

      // 查看 cookie 信息
      CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
      Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/" , false , client.getState().getCookies());
      if (cookies.length == 0) {
         System.out.println( "None" );
      } else {
         for ( int i = 0; i < cookies.length; i++) {
            System.out.println(cookies[i].toString());
         }
      }

      // 访问所需的页面 main2.jsp
      GetMethodget=newGetMethod("/main2.jsp");
      client.executeMethod(get);
      System.out.println(get.getResponseBodyAsString());
      get.releaseConnection();
   }
}

5. 提交XML格式参数

提交XML格式的参数很简单,仅仅是一个提交时候的ContentType问题,下面的例子演示从文件文件中读取XML信息并提交给服务器的过程,该过程可以用来测试Web服务。

import java.io.File;
import java.io.FileInputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;


/**
*用来演示提交XML格式数据的例子
*/

public class PostXMLClient {

   public static void main(String[] args) throws Exception {
      File input = new File(“test.xml”);
      PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp”);

      // 设置请求的内容直接从文件中读取
      post.setRequestBody( new FileInputStream(input));
      if (input.length() < Integer.MAX_VALUE)
         post.setRequestContentLength(input.length());
      else
         post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);

      // 指定请求内容的类型
      post.setRequestHeader( "Content-type" , "text/xml; charset=GBK" );
      HttpClient httpclient = new HttpClient();
      int result = httpclient.executeMethod(post);
      System.out.println( "Response status code: " + result);
      System.out.println( "Response body: " );
      System.out.println(post.getResponseBodyAsString());
      post.releaseConnection();
   }
}

6. 通过HTTP上传文件

httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面的代码片段演示如何使用这个类。

MultipartPostMethod filePost = new MultipartPostMethod(targetURL);
filePost.addParameter( "fileName" , targetFilePath);
HttpClient client = new HttpClient();

// 由于要上传的文件可能比较大 , 因此在此设置最大的连接超时时间
client.getHttpConnectionManager(). getParams().setConnectionTimeout(5000);
int status = client.executeMethod(filePost);



上面代码中,targetFilePath即为要上传的文件所在的路径。

7. 访问启用认证的页面

我们经常会碰到这样的页面,当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,这种用户认证的方式不同于我们在前面介绍的基于表单的用户身份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括:基本、摘要以及NTLM认证。其中基本认证最简单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式,而NTLM则是微软公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证还要安全的一种方式。

下面例子是从httpclient的CVS服务器中下载的,它简单演示如何访问一个认证保护的页面:


import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.GetMethod;

public class BasicAuthenticationExample {

   public BasicAuthenticationExample() {
   }

   public static void main(String[] args) throws Exception {
      HttpClient client = new HttpClient();
      client.getState().setCredentials( "www.verisign.com" , "realm" , new UsernamePasswordCredentials( "username" , "password" ) );

      GetMethod get = new GetMethod( "https://www.verisign.com/products/index.html" );
      get.setDoAuthentication( true );
      int status = client.executeMethod( get );
      System.out.println(status+ "\n" + get.getResponseBodyAsString());
      get.releaseConnection();
   }
}

8. 多线程模式下使用httpclient

多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类:MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,代码如下:

MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

HttpClient client = new HttpClient(connectionManager);

以后尽管访问client实例即可。
分享到:
评论

相关推荐

    HttpClient_学习整理.

    ### HttpClient 学习整理 #### 一、简介 `HttpClient`是Apache Jakarta Commons下的一个子项目,用于提供高效、最新及功能丰富的HTTP客户端编程工具包。对于那些希望通过HTTP协议访问网络资源的Java应用程序而言,...

    HttpClient3.1 学习整理

    HttpClient httpClient = new HttpClient(); GetMethod getMethod = new GetMethod("http://example.com"); int statusCode = httpClient.executeMethod(getMethod); if (statusCode == 200) { System.out....

    httpclient4中文API和使用

    `httpClient笔记.docx`可能是用户或教程作者整理的关于使用HttpClient的笔记或实战案例,可能包括一些常见问题的解决方案,比如处理重定向、处理cookies、上传下载文件、使用HTTPS等。 学习HttpClient时,除了API...

    JAVA核心知识点整理 全面整理.zip

    - **HTTP客户端**: 学习使用HttpURLConnection或HttpClient库发送HTTP请求并处理响应。 7. **反射机制** - **Class对象**: 理解如何获取类的信息,包括类名、方法、属性等。 - **动态代理**: 探究如何在运行时...

    最近在学习常用的Java开源项目,整理一下常用的代码.zip

    以下是对"最近在学习常用的Java开源项目,整理一下常用的代码.zip"这个压缩包中可能包含的知识点的详细解释: 1. **Maven或Gradle构建工具**:Java项目通常使用Maven或Gradle进行构建和依赖管理。通过查看项目的pom...

    基于Java的工具类学习项目.zip

    本项目是一个基于Java的工具类学习项目,旨在整理和演示各种工具类的使用方法。项目涵盖了从Excel处理、HTTP请求、JSON序列化到高性能网络框架Netty的使用等多个方面。通过本项目,开发者可以学习到如何使用这些工具...

    源码 网站交互&JSON&xml&Webservice 通过httpclient获取到JSON数据展示到ListView

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    安卓开发工具箱v2.8.5高级版.txt打包整理.zip

    "apache"可能指的是Apache开源项目,或者是使用了Apache相关的技术,例如Apache HttpClient或Apache Ant等,这些在Android开发中常见且重要。而"#资源达人分享计划#"可能是一个社区活动或者论坛的标签,表示这是由...

    安卓京东2022自动炸年兽v2.0.txt打包整理.zip

    "安卓京东2022自动炸年兽v2.0.txt打包整理.zip" 这个标题指的是一个针对安卓平台的京东应用程序,该应用可能是一个自动化工具,专为参与京东2022年的“炸年兽”活动而设计。炸年兽是京东在春节期间推出的一种互动...

    安卓点击助手v12.8绿化版.txt打包整理.zip

    描述中同样提到的是"安卓点击助手v12.8绿化版.txt打包整理.zip",这进一步确认了我们关注的是一个被整理过的文本文件集合,可能包含了关于这个绿化版应用的详细信息,如安装步骤、功能介绍、使用技巧等。 【标签...

    FaceLook项目源码整理

    "FaceLook项目源码整理"是一个专注于Java编程的开源项目,它可能包含了用于面部识别、图像处理或视觉计算的相关代码。这个项目的目的是为了让开发者能够学习、理解和应用相关的技术。从提供的文件列表来看,我们可以...

    轻松上手Java爬虫:CSDN文章抓取与整理.zip

    在本压缩包中,你将找到一个Java实现的CSDN文章抓取与整理的项目,这将是一个很好的起点来学习和实践Java爬虫技术。 首先,了解Java爬虫的基础是必不可少的。Java作为一种流行的编程语言,拥有强大的网络处理库,如...

    Java手机短信项目源码Java实用源码整理learns

    这是一份实用的源码整理,对于想要深入学习Java编程,特别是对Java在实际项目中的运用感兴趣的开发者来说,是非常有价值的参考资料。 1. **短信服务接口**:在Java项目中,通常会定义一个短信服务接口,这个接口...

    Java核心知识点整理.rar

    这份"Java核心知识点整理.rar"压缩包包含了对Java语言全面而深入的总结,对于初学者和有一定经验的开发者来说,都是宝贵的参考资料。下面,我们将详细探讨Java的核心知识点,并按照一个合理的学习路线进行阐述。 1....

    C#基类整理C#比较全的基类集合

    这个压缩包文件“C#基类整理C#比较全的基类集合”可能包含了一系列C#基础类的代码示例和解释,帮助开发者理解和运用这些类。 首先,我们来看一下C#中的几个关键基类: 1. **System.Object**:所有C#类的终极基类,...

    安卓可抖视v1.2.9免费版.txt打包整理.zip

    【标题解析】 "安卓可抖视v1.2.9免费版.txt打包...对于开发者而言,这个压缩包是一个学习和参考的宝贵资源,涵盖了实际开发中的多个方面,从编程语言到应用设计,再到商业运营,都是提升技能和了解行业趋势的重要途径。

    本人整理的一些常用的c#代码

    这个压缩包“本人整理的一些常用的c#代码”显然是一个针对初学者的学习资源集合,包含了各种实用的C#代码示例,旨在帮助新手快速掌握编程基础。 1. **基础语法**:C#的基础语法结构包括变量声明、数据类型(如int、...

    java+http+操作cookies源码整理

    这个源码整理主要关注如何在Java中使用HTTP进行Cookies的操作。以下是对这些知识点的详细解释。 首先,理解Cookies的基本概念。Cookies是由服务器端发送到客户端(浏览器)的一小段文本信息,用来存储用户的状态...

    Java常用代码整理

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高性能和丰富的类库而著名。"Java常用代码整理"这个主题涵盖了Java开发中的诸多常见技术点和...通过不断学习和实践,开发者可以更加熟练地驾驭这门强大的语言。

    s2深入.NET平台和C#编程课后、上机、指导练习答案项目案例和PPT

    学习者可以通过这个案例了解如何利用C#构建一个能够从服务器获取并显示新闻的应用,这将涉及HttpClient类的使用,XML或JSON数据的解析,以及WPF或WinForms的界面设计。 最后,"课程复习PPT"是整理了整个课程内容的...

Global site tag (gtag.js) - Google Analytics