我个人感觉这个就像JQUERY的AJAX设计一样,简化一次HTTP请求的代码数量,可以像流水线一样往请求上添加需要的头、内容、参数。
5.1.请求facade API
从4.2版本开始,HttpClient自带了一个易于使用的facade API,基于fluent interface的概念。Fluent facade API仅暴露了HttpClient的最基本功能,旨在用于不需要HttpClient的完全灵活性的简单用例。例如, fluent facade API使用户不必处理连接管理和资源释放。
通过 HC fluent API以下是执行的HTTP请求的几个示例:
Request.Get("http://www.baidu.com")
.socketTimeout(1000)
.connectTimeout(1000)
.body(new StringEntity(""))
.addHeader("","")
.execute().returnContent().asString();
// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,
// containing a request body as String and return response content as byte array.
Request.Post("http://somehost/do-stuff")
.useExpectContinue()
.version(HttpVersion.HTTP_1_1)
.bodyString("Important stuff", ContentType.DEFAULT_TEXT)
.execute().returnContent().asBytes();
// Execute a POST with a custom header through the proxy containing a request body
// as an HTML form and save the result to the file
Request.Post("http://somehost/some-form")
.addHeader("X-Custom-header", "stuff")
.viaProxy(new HttpHost("myproxy", 8080))
.bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
.execute().saveContent(new File("result.dump"));
还可以直接使用Executor,以便在特定的安全上下文中执行请求,从而将身份验证细节缓存并重新用于后续请求。
Executor executor = Executor.newInstance()
.auth(new HttpHost("somehost"), "username", "password")
.auth(new HttpHost("myproxy", 8080), "username", "password")
.authPreemptive(new HttpHost("myproxy", 8080));
executor.execute(Request.Get("http://somehost/"))
.returnContent().asString();
executor.execute(Request.Post("http://somehost/do-stuff")
.useExpectContinue()
.bodyString("Important stuff", ContentType.DEFAULT_TEXT))
.returnContent().asString();
5.1.1. Response 处理
fluent facade API通常减轻用户不必处理连接管理和资源释放。然而,在大多数情况下,这是以缓冲内存中的响应消息内容为代价的。 强烈建议使用ResponseHandler进行HTTP响应处理,以避免在内存中缓冲的内容丢失。
Document result = Request.Get("http://somehost/content")
.execute().handleResponse(new ResponseHandler<Document>() {
public Document handleResponse(final HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
ContentType contentType = ContentType.getOrDefault(entity);
if (!contentType.equals(ContentType.APPLICATION_XML)) {
throw new ClientProtocolException("Unexpected content type:" +
contentType);
}
String charset = contentType.getCharset().displayName();
if (charset == null) {
charset = "UTF-8";
}
return docBuilder.parse(entity.getContent(), charset);
} catch (ParserConfigurationException ex) {
throw new IllegalStateException(ex);
} catch (SAXException ex) {
throw new ClientProtocolException("Malformed XML document", ex);
}
}
});
总结:我个人感觉这个功能非常的棒,如果对于HTTP请求报文设置相对较少或者需求较为简单这种方法处理很方便,减少了很多臃肿的代码。