HttpClient的快速使用

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。

http的主要功能包括:

1. 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

2. 支持自动转向

3. 支持 HTTPS 协议

4. 支持代理服务器等

使用 HttpClient 需要以下 6 个步骤:

1. 创建 HttpClient 的实例

2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

4. 读 response

5. 释放连接。无论执行方法是否成功,都必须释放连接

6. 对得到后的内容进行处理

根据以上步骤,我们来编写用GET方法来取得某网页内容的代码。

大部分情况下 HttpClient 默认的构造函数已经足够使用。
HttpClient httpClient = new HttpClient();
创建GET方法的实例。在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程,如果想要把自动处理转发过程去掉的话,可以调用方法setFollowRedirects(false)。
GetMethod getMethod = new GetMethod("http://www.ibm.com/");

调用实例httpClient的executeMethod方法来执行getMethod。由于是执行在网络上的程序,在运行executeMethod方法的时候,需要处理两个异常,分别是HttpException和IOException。引起第一种异常的原因主要可能是在构造getMethod的时候传入的协议不对,比如不小心将"http"写成"htp",或者服务器端返回的内容不正常等,并且该异常发生是不可恢复的;第二种异常一般是由于网络原因引起的异常,对于这种异常 (IOException),HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试3次。executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码,该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳转的)等。//设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); //执行getMethod int statusCode = client.executeMethod(getMethod); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + getMethod.getStatusLine()); } 在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:第一种,getResponseBody,该方法返回的是目标的二进制的byte流;第二种,getResponseBodyAsString,这个方法返回的是String类型,值得注意的是该方法返回的String的编码是根据系统默认的编码方式,所以返回的String值可能编码类型有误,在本文的"字符编码"部分中将对此做详细介绍;第三种,getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的getResponseBody方法。
byte[] responseBody = method.getResponseBody();

释放连接。无论执行方法是否成功,都必须释放连接。
method.releaseConnection();

处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。
System.out.println(new String(responseBody));


完整的代码示例:

public class FeedBackServiceImpl implements FeedBackService, InitializingBean { private static final Logger log = LoggerFactory.getLogger(FeedBackServiceImpl.class); private static final int CONNECTION_TIME_OUT = 1000; private static final int TIME_OUT = 2000; /** * 参数 */ private static final String PARAM_ID = "id"; private static final String PARAM_QUESTION_ID = "questionId"; private static final String PARAM_ANSWER = "answer"; private static final String PARAM_COOKIE_ID = "cookieId"; /** * 盖娅系统获取调查问卷的url */ private String feedBackQuestionaireUrl; /** * 盖娅系统保存用户反馈信息的url */ private String feedBackAnswerUrl; /** * 问卷类型与问卷id的映射 * * <pre> * 问卷类型,从前台传递过来。目前有两个取值:"1"表示进货单页面的问卷;"2"表示确认订单页面的问卷 * 问卷id,作为从盖娅系统中获取调查问卷的参数 * </pre> */ private Map<String, String> questionTypeToQuestionId = new HashMap<String, String>(); private HttpClient httpClient; public boolean addFeedBack(FeedBackModel feedBackModel) { if (feedBackModel == null) { return false; } boolean res = false; // 调用盖娅系统的接口,提交反馈 PostMethod postMethod = new PostMethod(feedBackAnswerUrl); postMethod.addParameter(PARAM_QUESTION_ID, feedBackModel.getQuestionId()); postMethod.addParameter(PARAM_ANSWER, feedBackModel.getAnswer()); postMethod.addParameter(PARAM_COOKIE_ID, feedBackModel.getCookieId()); try { int statusCode = httpClient.executeMethod(postMethod); if (statusCode != HttpStatus.SC_OK) { StringBuilder sb = new StringBuilder("fail to add feedback, requestUrl="); sb.append(feedBackAnswerUrl).append(", parameter: ").append(feedBackModel.toString()).append(", HTTP StatusCode=").append(statusCode); log.error(sb.toString()); res = false; } else { res = true; } } catch (HttpException e) { log.error("HttpException occured when addFeedBack, requestUrl=" + feedBackAnswerUrl + ", parameter: " + feedBackModel.toString(), e); res = false; } catch (IOException e) { log.error("IOException occured when addFeedBack, requestUrl=" + feedBackAnswerUrl + ", parameter: " + feedBackModel.toString(), e); res = false; } finally { postMethod.releaseConnection(); postMethod = null; } return res; } public JSONObject getQuestionaire(String questionType) { String id = questionTypeToQuestionId.get(questionType); if (StringUtil.isBlank(id)) { return null; } // 调用盖娅系统的接口,获取调查问卷 GetMethod getMethod = new GetMethod(feedBackQuestionaireUrl); NameValuePair param = new NameValuePair(PARAM_ID, id); getMethod.setQueryString(new NameValuePair[]{param}); String responseText = null; try { // 执行getMethod int statusCode = httpClient.executeMethod(getMethod); if (statusCode != HttpStatus.SC_OK) { StringBuilder sb = new StringBuilder("fail to getQuestionaire, requestUrl="); sb.append(feedBackQuestionaireUrl).append("?id=").append(id).append(", HTTP StatusCode=").append(statusCode); log.error(sb.toString()); return null; } // 读取内容 responseText = getMethod.getResponseBodyAsString(); } catch (HttpException e) { StringBuilder sb = new StringBuilder("HttpException occured when getQuestionaire, requestUrl="); sb.append(feedBackQuestionaireUrl).append("?id=").append(id); log.error(sb.toString(), e); return null; } catch (IOException e) { StringBuilder sb = new StringBuilder("IOException occured when getQuestionaire, requestUrl="); sb.append(feedBackQuestionaireUrl).append("?id=").append(id); log.error(sb.toString(), e); return null; } finally { getMethod.releaseConnection(); getMethod = null; } if (StringUtil.isBlank(responseText)) { return null; } // 从查询结果中解析出包含问卷的json字符串 int index = responseText.indexOf("="); if (index >= 0) { responseText = responseText.substring(index + 1); } try { JSONObject json = JSONObject.fromObject(responseText); return json; } catch (Exception e) { log.error("fail to change from String to JSONObject, string=" + responseText, e); return null; } } public void afterPropertiesSet() throws Exception { HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); httpClient = new HttpClient(connectionManager); httpClient.setConnectionTimeout(CONNECTION_TIME_OUT); httpClient.setTimeout(TIME_OUT); }
更多资料请参考: http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值