HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

一、实现功能

1、实现了所有 HTTP 的方法,读取网页内容(GET,POST,PUT,HEAD 等)

2、支持自动转向

3、支持 HTTPS 协议

4、支持代理服务器等

更多功能请自行参考HttpClient官方文档

1.读取网页(HTTP/HTTPS)内容

步骤如下:首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。

/**

         *最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面

          *@authorLiudong

        */

        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://java.sun.com");

              //使用POST方法

              //HttpMethod method = new PostMethod("http://java.sun.com");

               client.executeMethod(method);

              //打印服务器返回的状态

              System.out.println(method.getStatusLine());

              //打印返回的信息

              System.out.println(method.getResponseBodyAsString());

              //释放连接

              method.releaseConnection();

           }

        }

2.使用POST方式提交数据

HttpClient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面这里将给出关于两种模拟上传方式的代码

2.1.模拟上传url文件(该方式也适合做普通post请求):

   /**

     * 上传url文件到指定URL

     * @param fileUrl 上传图片url

     * @param postUrl 上传路径及参数,注意有些中文参数需要使用预先编码 eg : URLEncoder.encode(appName, "UTF-8")

     * @return

     * @throws IOException

     */

    public static String doUploadFile(String postUrl) throws IOException {

        if(StringUtils.isEmpty(postUrl))

            return null;

        String response = "";

        PostMethod postMethod = new PostMethod(postUrl);

        try {

            HttpClient client = new HttpClient();

            client.getHttpConnectionManager().getParams()

                    .setConnectionTimeout(50000);// 设置连接时间

            int status = client.executeMethod(postMethod);

            if (status == HttpStatus.SC_OK) {

                InputStream inputStream = postMethod.getResponseBodyAsStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(

                        inputStream));

                StringBuffer stringBuffer = new StringBuffer();

                String str = "";

                while ((str = br.readLine()) != null) {

                    stringBuffer.append(str);

                }

                response = stringBuffer.toString();

            } else {

                response = "fail";

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            // 释放连接

            postMethod.releaseConnection();

        }

        return response;

    }

  

2.2.模拟文件上传到指定位置

  /**

     * 上传文件到指定URL

     * @param file

     * @param url

     * @return

     * @throws IOException

     */

    public static String doUploadFile(File file, String url) throws IOException {

        String response = "";

        if (!file.exists()) {

            return "file not exists";

        }

        PostMethod postMethod = new PostMethod(url);

        try {

            //----------------------------------------------

            // FilePart:用来上传文件的类,file即要上传的文件

            FilePart fp = new FilePart("file", file);

            Part[] parts = { fp };

            // 对于MIME类型的请求,httpclient建议全用MulitPartRequestEntity进行包装

            MultipartRequestEntity mre = new MultipartRequestEntity(parts,

                    postMethod.getParams());

            postMethod.setRequestEntity(mre);

            //---------------------------------------------

            HttpClient client = new HttpClient();

            client.getHttpConnectionManager().getParams()

                    .setConnectionTimeout(50000);// 由于要上传的文件可能比较大 , 因此在此设置最大的连接超时时间

            int status = client.executeMethod(postMethod);

            if (status == HttpStatus.SC_OK) {

                InputStream inputStream = postMethod.getResponseBodyAsStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(

                        inputStream));

                StringBuffer stringBuffer = new StringBuffer();

                String str = "";

                while ((str = br.readLine()) != null) {

                    stringBuffer.append(str);

                }

                response = stringBuffer.toString();

            } else {

                response = "fail";

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            // 释放连接

            postMethod.releaseConnection();

        }

        return response;

    }

3.处理页面重定向

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

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

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 地址

   Header header=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方法重定向到另外一个页面用来测试上面的例子。

浅析HttpCient的更多相关文章

  1. SQL Server on Linux 理由浅析

    SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...

  2. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. 高性能IO模型浅析

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking  ...

  4. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

  5. Jvm 内存浅析 及 GC个人学习总结

    从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...

  6. 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler

    熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

  7. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  8. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  9. word-break|overflow-wrap|word-wrap——CSS英文断句浅析

    ---恢复内容开始--- word-break|overflow-wrap|word-wrap--CSS英文断句浅析 一 问题引入 今天在再次学习 overflow 属性的时候,查看效果时,看到如下结 ...

随机推荐

  1. oo面向对象--规格化设计

    oo面向对象--规格化设计 规格化设计与抽象 要了解规格化设计首先要了解抽象化的程序设计,两者是密不可分的. 抽象化(Abstraction) 抽象化是将数据与程序,用语义呈现他们的外观,但是隐藏起它 ...

  2. C语言基础:分支语句和常见运算符 分类: iOS学习 c语言基础 2015-06-10 21:44 13人阅读 评论(0) 收藏

    if(判断条件){ 执行语句; }else if(判断条件){ 执行语句; } switch (整型表达式){  case 值1: 执行语句; break; case 值2: 执行语句; break; ...

  3. tomcat版本号的修改

    我的是8.5.0我将其改为8.0.0    其他版本改也是一样      我改这个版本号就是因为eclipse上没有tomcat8.5.0的配置  所以将其改为8.0.0     在配置web服务器时 ...

  4. BZOJ5091: [Lydsy1711月赛]摘苹果【期望DP】

    Description 小Q的工作是采摘花园里的苹果.在花园中有n棵苹果树以及m条双向道路,苹果树编号依次为1到n,每条道路的两 端连接着两棵不同的苹果树.假设第i棵苹果树连接着d_i条道路.小Q将会 ...

  5. ElasticSearch—分页查询

    ElasticSearch查询—分页查询详解 Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.那么,如何实现分页查询呢? 按照一般的查询流程来说,如 ...

  6. hdu2064

    hdu2064 汉诺塔变形,数学题 #include<stdio.h> ]; int main(){ A[]=; int i; ;i<=;i++){ A[i]=*A[i-]+; } ...

  7. 实习第二天-java参数传递-精华在文章最后2句话

    对于基本类型的传递,我们很容易理解,而对于对象,总让人感觉是按引用传递,看下面的程序: public class ObjectRef { //基本类型的参数传递 public static void ...

  8. CSI-MIPI学习笔记

    一.mipi LCD 的CLK时钟频率与显示分辨率及帧率的关系 公式: Mipiclock = [ (width+hsync+hfp+hbp) x (height+vsync+vfp+vbp) ] x ...

  9. treeql 基于rest 标准的接口开发协议

    treeql 可以让我们按照数据库的关系模型,生成一个tree 模型的json 数据,基于rest 标准, 从设计上,来说还是很不错的,但是从长远发展来说graphql 应该会更好,也有相关的比较 参 ...

  10. 破解UltraEdit(Ver20.00.0.1040),无限试用

    因为是第一次破解较大型的商业软件,所以有必要记录一下,另外UE的价格也实在太贵了... 第零步:准备 准备好破解常用软件.我常用的工具有IDA(用于静态分析).Ollydbg(动态调试).PEiD(用 ...