相比于HttpClient 之前的版本号,HttpClient 4.2 提供了一组基于流接口(fluent interface)概念的更易使用的API,即Fluent API.
为了方便使用,Fluent API仅仅暴露了一些最主要的HttpClient功能。
这样,Fluent API就将开发人员从连接管理、资源释放等繁杂的操作中解放出来,从而更易进行一些HttpClient的简单操作。
(原文地址:http://blog.****.net/vector_yi/article/details/24298629转载请注明出处)
还是利用详细样例来说明吧。
下面是几个使用Fluent API的代码例子:
一、最主要的http请求功能
运行Get、Post请求,不正确返回的响应作处理
package com.vectoryi.fluent; import java.io.File; import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType; public class FluentRequests { public static void main(String[] args)throws Exception {
//运行一个GET请求,同一时候设置Timeout參数并将响应内容作为String返回
Request.Get("http://blog.****.net/vector_yi")
.connectTimeout(1000)
.socketTimeout(1000)
.execute().returnContent().asString(); //以Http/1.1版本号协议运行一个POST请求,同一时候配置Expect-continue handshake达到性能调优,
//请求中包括String类型的请求体并将响应内容作为byte[]返回
Request.Post("http://blog.****.net/vector_yi")
.useExpectContinue()
.version(HttpVersion.HTTP_1_1)
.bodyString("Important stuff", ContentType.DEFAULT_TEXT)
.execute().returnContent().asBytes(); //通过代理运行一个POST请求并加入一个自己定义的头部属性,请求包括一个HTML表单类型的请求体
//将返回的响应内容存入文件
Request.Post("http://blog.****.net/vector_yi")
.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"));
} }
二、在后台线程中异步运行多个请求
package com.vectoryi.fluent; import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; import org.apache.http.client.fluent.Async;
import org.apache.http.client.fluent.Content;
import org.apache.http.client.fluent.Request;
import org.apache.http.concurrent.FutureCallback; public class FluentAsync { public static void main(String[] args)throws Exception {
// 利用线程池
ExecutorService threadpool = Executors.newFixedThreadPool(2);
Async async = Async.newInstance().use(threadpool); Request[] requests = new Request[] {
Request.Get("http://www.google.com/"),
Request.Get("http://www.yahoo.com/"),
Request.Get("http://www.apache.com/"),
Request.Get("http://www.apple.com/")
}; Queue<Future<Content>> queue = new LinkedList<Future<Content>>();
// 异步运行GET请求
for (final Request request: requests) {
Future<Content> future = async.execute(request, new FutureCallback<Content>() { public void failed(final Exception ex) {
System.out.println(ex.getMessage() + ": " + request);
} public void completed(final Content content) {
System.out.println("Request completed: " + request);
} public void cancelled() {
} });
queue.add(future);
} while(!queue.isEmpty()) {
Future<Content> future = queue.remove();
try {
future.get();
} catch (ExecutionException ex) {
}
}
System.out.println("Done");
threadpool.shutdown();
} }
三、更高速地启动请求
package com.vectoryi.fluent; import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request; public class FluentQuickStart { public static void main(String[] args) throws Exception { Request.Get("http://targethost/homepage")
.execute().returnContent();
Request.Post("http://targethost/login")
.bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
.execute().returnContent();
}
}
四、处理Response
在本例中是利用xmlparsers来解析返回的ContentType.APPLICATION_XML类型的内容。
package com.vectoryi.fluent; import java.io.IOException;
import java.nio.charset.Charset; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.w3c.dom.Document;
import org.xml.sax.SAXException; public class FluentResponseHandling { public static void main(String[] args)throws Exception {
Document result = Request.Get("http://www.baidu.com")
.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);
}
Charset charset = contentType.getCharset();
if (charset == null) {
charset = Consts.ISO_8859_1;
}
return docBuilder.parse(entity.getContent(), charset.name());
} catch (ParserConfigurationException ex) {
throw new IllegalStateException(ex);
} catch (SAXException ex) {
throw new ClientProtocolException("Malformed XML document", ex);
}
} });
// 处理得到的result
System.out.println(result);
} }