httpClient 学习总结

来源:互联网 发布:搜狗输入法用户数据 编辑:程序博客网 时间:2024/04/29 12:12

httpClient 常用功能


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

/**
 * 最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
 */
public class SimpleClient {
    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient();   //创建一个客户端
        // 使用 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();
    }
}

首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。

2、使用POST方式提交数据(httpClient3)

第一种:模拟上传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;
    }

第二种:模拟文件上传到指定位置

/**
     * 上传文件到指定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. 处理页面重定向

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

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");}

4. 模拟登录开心网

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

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

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

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import org.apache.commons.httpclient.Cookie;import org.apache.commons.httpclient.Header;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpStatus;import org.apache.commons.httpclient.NameValuePair;import org.apache.commons.httpclient.cookie.CookiePolicy;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.PostMethod;import org.apache.commons.httpclient.params.HttpClientParams;import org.apache.commons.httpclient.params.HttpMethodParams;class Login {    public static String loginurl = "https://security.kaixin001.com/login/login_post.php";    static Cookie[] cookies = {};    static HttpClient httpClient = new HttpClient();        static String email = "xxx@qq.com";//你的email    static String psw = "xxx";//你的密码    // 消息发送的action    String url = "http://www.kaixin001.com/home/";    public static void getUrlContent()            throws Exception {        HttpClientParams httparams = new HttpClientParams();        httparams.setSoTimeout(30000);        httpClient.setParams(httparams);        httpClient.getHostConfiguration().setHost("www.kaixin001.com", 80);        httpClient.getParams().setParameter(                HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");        PostMethod login = new PostMethod(loginurl);        login.addRequestHeader("Content-Type",                "application/x-www-form-urlencoded; charset=UTF-8");        NameValuePair Email = new NameValuePair("loginemail", email);// 邮箱        NameValuePair password = new NameValuePair("password", psw);// 密码        // NameValuePair code = new NameValuePair( "code"        // ,"????");//有时候需要验证码,暂时未解决        NameValuePair[] data = { Email, password };        login.setRequestBody(data);        httpClient.executeMethod(login);        int statuscode = login.getStatusCode();        System.out.println(statuscode + "-----------");        String result = login.getResponseBodyAsString();        System.out.println(result+"++++++++++++");        cookies = httpClient.getState().getCookies();        System.out.println("==========Cookies============");        int i = 0;        for (Cookie c : cookies) {            System.out.println(++i + ":   " + c);        }        httpClient.getState().addCookies(cookies);        // 当state为301或者302说明登陆页面跳转了,登陆成功了        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY)                || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY)                || (statuscode == HttpStatus.SC_SEE_OTHER)                || (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {            // 读取新的 URL 地址            Header header = login.getResponseHeader("location");            // 释放连接            login.releaseConnection();            System.out.println("获取到跳转header>>>" + header);            if (header != null) {                String newuri = header.getValue();                if ((newuri == null) || (newuri.equals("")))                    newuri = "/";                GetMethod redirect = new GetMethod(newuri);                // ////////////                redirect.setRequestHeader("Cookie", cookies.toString());                httpClient.executeMethod(redirect);                System.out.println("Redirect:"                        + redirect.getStatusLine().toString());                redirect.releaseConnection();            } else                System.out.println("Invalid redirect");        } else {            // 用户名和密码没有被提交,当登陆多次后需要验证码的时候会出现这种未提交情况            System.out.println("用户没登陆");            System.exit(1);        }    }    public static void sendMsg() throws Exception {        // 登录后发消息        System.out.println("*************发消息***********");        String posturl = "http://www.kaixin001.com/msg/post.php";        PostMethod poster = new PostMethod(posturl);        poster.addRequestHeader("Content-Type",                "application/x-www-form-urlencoded; charset=UTF-8");        poster.setRequestHeader("Cookie", cookies.toString());        NameValuePair uids = new NameValuePair("uids", "89600585");// 发送的好友对象的id,此处换成你的好友id        NameValuePair content = new NameValuePair("content", "你好啊!");// 需要发送的信息的内容        NameValuePair liteeditor_0 = new NameValuePair("liteeditor_0", "你好啊!");// 需要发送的信息的内容        NameValuePair texttype = new NameValuePair("texttype", "plain");        NameValuePair send_separate = new NameValuePair("send_separate", "0");        NameValuePair service = new NameValuePair("service", "0");        NameValuePair[] msg = { uids, content, texttype, send_separate, service,liteeditor_0 };        poster.setRequestBody(msg);        httpClient.executeMethod(poster);        String result = poster.getResponseBodyAsString();        System.out.println(result+"++++++++++++");        //System.out.println(StreamOut(result, "iso8859-1"));        int statuscode = poster.getStatusCode();        System.out.println(statuscode + "-----------");        if(statuscode == 301 || statuscode == 302){            // 读取新的 URL 地址            Header header = poster.getResponseHeader("location");            System.out.println("获取到跳转header>>>" + header);            if (header != null) {                String newuri = header.getValue();                if ((newuri == null) || (newuri.equals("")))                    newuri = "/";                GetMethod redirect = new GetMethod(newuri);                // ////////////                redirect.setRequestHeader("Cookie", cookies.toString());                httpClient.executeMethod(redirect);                System.out.println("Redirect:"                        + redirect.getStatusLine().toString());                redirect.releaseConnection();            } else                System.out.println("Invalid redirect");        }                    poster.releaseConnection();    }    public static String StreamOut(InputStream txtis, String code)            throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(txtis,                code));        String tempbf;        StringBuffer html = new StringBuffer(100);        while ((tempbf = br.readLine()) != null) {            html.append(tempbf + "\n");        }        return html.toString();    }}

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();    } }







2 0
原创粉丝点击