HttpClient简介
HTTP 协议多是如今 Internet 上使用得最多、最重要的协议了,愈来愈多的 Java 应用程序须要直接经过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,可是对于大部分应用程序来讲,JDK 库自己提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,而且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在不少的项目中,好比 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。更多信息请关注http://hc.apache.org/php
HttpClient 功能介绍
如下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能能够参见 HttpClient 的主页。html
实现了全部 HTTP 的方法(GET,POST,PUT,HEAD 等)java
支持自动转向apache
支持 HTTPS 协议编程
支持代理服务器等浏览器
应用HttpClient来对付各类顽固的WEB服务器
转自:http://blog.csdn.net/ambitiontan/archive/2006/01/06/572171.aspx安全
通常的状况下咱们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅仅是一些普通的页面,有的须要用户登陆后方可以使用,或者须要认证以及是一些经过加密方式传输,例如HTTPS。目前咱们使用的浏览器处理这些状况都不会构成问题。不过你可能在某些时候须要经过程序来访问这样的一些页面,好比从别人的网页中“偷”一些数据;利用某些站点提供的页面来完成某种功能,例如说咱们想知道某个手机号码的归属地而咱们本身又没有这样的数据,所以只好借助其余公司已有的网站来完成这个功能,这个时候咱们须要向网页提交手机号码并从返回的页面中解析出咱们想要的数据来。若是对方仅仅是一个很简单的页面,那咱们的程序会很简单,本文也就没有必要大张旗鼓的在这里浪费口舌。可是考虑到一些服务受权的问题,不少公司提供的页面每每并非能够经过一个简单的URL就能够访问的,而必须通过注册而后登陆后方可以使用提供服务的页面,这个时候就涉及到COOKIE问题的处理。咱们知道目前流行的动态网页技术例如ASP、JSP无不是经过COOKIE来处理会话信息的。为了使咱们的程序能使用别人所提供的服务页面,就要求程序首先登陆后再访问服务页面,这过程就须要自行处理cookie,想一想当你用java.net.HttpURLConnection来完成这些功能时是多么恐怖的事情啊!何况这仅仅是咱们所说的顽固的WEB服务器中的一个很常见的“顽固”!再有如经过HTTP来上传文件呢?不须要头疼,这些问题有了“它”就很容易解决了!服务器
咱们不可能列举全部可能的顽固,咱们会针对几种最多见的问题进行处理。固然了,正如前面说到的,若是咱们本身使用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情,所以在开始以前咱们先要介绍一下一个开放源码的项目,这个项目就是Apache开源组织中的httpclient,它隶属于Jakarta的commons项目,目前的版本是2.0RC2。commons下原本已经有一个net的子项目,可是又把httpclient单独提出来,可见http服务器的访问绝非易事。cookie
Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各类通信编程。经过它可让原来很头疼的事情如今轻松的解决,例如你再也不管是HTTP或者HTTPS的通信方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。本文会针对咱们在编写HTTP客户端程序时常常碰到的几个问题进行分别介绍如何使用httpclient来解决它们,为了让读者更快的熟悉这个项目咱们最开始先给出一个简单的例子来读取一个网页的内容,而后按部就班解决掉前进中的全部问题。网络
1. 读取网页(HTTP/HTTPS)内容
下面是咱们给出的一个简单的例子用来访问某个页面
/** *最简单的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(); } }
在这个例子中首先建立一个HTTP客户端(HttpClient)的实例,而后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就能够搞定整个请求的过程,很是的简单!
二、使用POST方式提交数据(httpClient3)
httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,咱们要作的仅仅是告诉它咱们要上传文件的全路径便可,下面这里将给出关于两种模拟上传方式的代码
第一种:模拟上传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. 处理页面重定向
在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方法重定向到另一个页面用来测试上面的例子。
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(); } }
6. 访问启用认证的页面
咱们常常会碰到这样的页面,当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,这种用户认证的方式不一样于咱们在前面介绍的基于表单的用户身份验证。这是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(); } }
7. 多线程模式下使用
多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证多线程工做环境下不产生冲突,httpclient使用了一个多线程链接管理器的类:MultiThreadedHttpConnectionManager,要使用这个类很简单,只须要在构造HttpClient实例的时候传入便可,代码以下:
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);
之后尽管访问client实例便可。
httpClient完整封装
HttpInvoke.java:封装了HttpClient调度的必要参数设置,以及post,get等经常使用方法
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.GetMethod; import java.util.Iterator; import java.util.Map; import java.net.SocketTimeoutException; import java.io.BufferedReader; import java.io.InputStreamReader; public class HttpInvoker { private Log logger = LogFactory.getLog(HttpInvoker.class); private static HttpInvoker httpInvoker = new HttpInvoker(); private HttpClient client = null; private String charset = "gbk"; private int timeout = 10000; private boolean useProxy = false; private String proxyHost = null; private int proxyPort; private String proxyUsername = null; private String proxyPassword = null; private boolean initialized = false; public static HttpInvoker getInstance() { return httpInvoker; } private HttpInvoker() { client = new HttpClient(new MultiThreadedHttpConnectionManager()); client.getParams().setParameter("http.protocol.content-charset", "gbk"); client.getParams().setContentCharset("gbk"); client.getParams().setSoTimeout(timeout); } public HttpInvoker(String charset, int timeout, boolean useProxy, String proxyHost, int proxyPort, String proxyUsername, String proxyPassword) { client = new HttpClient(new MultiThreadedHttpConnectionManager()); if(charset != null && !charset.trim().equals("")) { this.charset = charset; } if(timeout > 0) { this.timeout = timeout; } client.getParams().setParameter("http.protocol.content-charset", charset); client.getParams().setContentCharset(charset); client.getParams().setSoTimeout(timeout); if(useProxy && proxyHost != null && !proxyHost.trim().equals("") && proxyPort > 0) { HostConfiguration hc = new HostConfiguration(); hc.setProxy(proxyHost, proxyPort); client.setHostConfiguration(hc); if (proxyUsername != null && !proxyUsername.trim().equals("") && proxyPassword != null && !proxyPassword.trim().equals("")) { client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUsername, proxyPassword)); } } initialized = true; logger.debug("HttpInvoker初始化完成"); } public synchronized void init() { if(charset != null && !charset.trim().equals("")) { client.getParams().setParameter("http.protocol.content-charset", charset); client.getParams().setContentCharset(charset); } if(timeout > 0) { client.getParams().setSoTimeout(timeout); } if(useProxy && proxyHost != null && !proxyHost.trim().equals("") && proxyPort > 0) { HostConfiguration hc = new HostConfiguration(); hc.setProxy(proxyHost, proxyPort); client.setHostConfiguration(hc); if (proxyUsername != null && !proxyUsername.trim().equals("") && proxyPassword != null && !proxyPassword.trim().equals("")) { client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUsername, proxyPassword)); } } initialized = true; logger.debug("HttpInvoker初始化完成"); } public String invoke(String url) throws Exception { return invoke(url, null, false); } public String invoke(String url, Map params, boolean isPost) throws Exception { logger.debug("HTTP调用[" + (isPost?"POST":"GET") + "][" + url + "][" + params + "]"); HttpMethod httpMethod = null; String result = ""; try { if(isPost && params != null && params.size() > 0) { Iterator paramKeys = params.keySet().iterator(); httpMethod = new PostMethod(url); NameValuePair[] form = new NameValuePair[params.size()]; int formIndex = 0; while(paramKeys.hasNext()) { String key = (String)paramKeys.next(); Object value = params.get(key); if(value != null && value instanceof String && !value.equals("")) { form[formIndex] = new NameValuePair(key, (String)value); formIndex++; } else if(value != null && value instanceof String[] && ((String[])value).length > 0) { NameValuePair[] tempForm = new NameValuePair[form.length + ((String[])value).length - 1]; for(int i=0; i<formIndex; i++) { tempForm[i] = form[i]; } form = tempForm; for(String v : (String[])value) { form[formIndex] = new NameValuePair(key, (String)v); formIndex++; } } } ((PostMethod)httpMethod).setRequestBody(form); } else { if(params != null && params.size() > 0) { Iterator paramKeys = params.keySet().iterator(); StringBuffer getUrl = new StringBuffer(url.trim()); if(url.trim().indexOf("?") > -1) { if(url.trim().indexOf("?") < url.trim().length()-1 && url.trim().indexOf("&") < url.trim().length()-1) { getUrl.append("&"); } } else { getUrl.append("?"); } while(paramKeys.hasNext()) { String key = (String)paramKeys.next(); Object value = params.get(key); if(value != null && value instanceof String && !value.equals("")) { getUrl.append(key).append("=").append(value).append("&"); } else if(value != null && value instanceof String[] && ((String[])value).length > 0) { for(String v : (String[])value) { getUrl.append(key).append("=").append(v).append("&"); } } } if(getUrl.lastIndexOf("&") == getUrl.length()-1) { httpMethod = new GetMethod(getUrl.substring(0, getUrl.length()-1)); } else { httpMethod = new GetMethod(getUrl.toString()); } } else { httpMethod = new GetMethod(url); } } client.executeMethod(httpMethod); // result = httpMethod.getResponseBodyAsString(); BufferedReader reader = new BufferedReader(new InputStreamReader( httpMethod.getResponseBodyAsStream(),"ISO-8859-1")); String line = null; String html = null; while((line = reader.readLine()) != null){ if(html == null) { html = ""; } else { html += "\r\n"; } html += line; } if(html != null) { result = new String(html.getBytes("ISO-8859-1"), charset); } } catch (SocketTimeoutException e) { logger.error("链接超时[" + url + "]"); throw e; } catch (java.net.ConnectException e) { logger.error("链接失败[" + url + "]"); throw e; } catch (Exception e) { logger.error("链接时出现异常[" + url + "]"); throw e; } finally { if (httpMethod != null) { try { httpMethod.releaseConnection(); } catch (Exception e) { logger.error("释放网络链接失败[" + url + "]"); throw e; } } } return result; } public void setCharset(String charset) { this.charset = charset; } public void setTimeout(int timeout) { this.timeout = timeout; } public void setProxyHost(String proxyHost) { this.proxyHost = proxyHost; } public void setProxyPort(int proxyPort) { this.proxyPort = proxyPort; } public void setProxyUsername(String proxyUsername) { this.proxyUsername = proxyUsername; } public void setProxyPassword(String proxyPassword) { this.proxyPassword = proxyPassword; } public void setUseProxy(boolean useProxy) { this.useProxy = useProxy; } public synchronized boolean isInitialized() { return initialized; } }
http访问网络的代理ip和端口,还有使用用户及密码均可以在Spring容器中注入进来:
<bean id="httpInvoker" class="HttpInvoker"> <constructor-arg type="java.lang.String" value="gbk" /><!--useProxy--> <constructor-arg type="int" value="10000" /><!--useProxy--> <constructor-arg type="boolean" value="true" /><!--useProxy--> <!--代理地址 --> <constructor-arg type="java.lang.String" value="192.168.1.1" /> <constructor-arg type="int" value="8080" /> <constructor-arg type="java.lang.String" value="" /><!--用户名--> <constructor-arg type="java.lang.String" value="" /><!--密码--> </bean>
使用方式:post
Map<String,String> params = new HashMap<String,String>(); params.put("check", check); String result = httpInvoker.invoke( "someURL", params, true);
使用方式:get
String content = httpInvoker.invoke(url);