Tweaked fluent API
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1189929 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d8b5071301
commit
41cfb9bbea
|
@ -2,4 +2,5 @@
|
|||
.project
|
||||
.settings
|
||||
.clover
|
||||
.externalToolBuilders
|
||||
target
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.fluent;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.entity.ContentType;
|
||||
|
||||
/**
|
||||
* This example demonstrates how the he HttpClient fluent API can be used to execute multiple
|
||||
* requests within the same security context. The Executor class maintains a common context shared
|
||||
* by all requests executed with it. The Executor is thread-safe and can be used to execute
|
||||
* requests concurrently from multiple threads of execution.
|
||||
*/
|
||||
public class FluentExecutor {
|
||||
|
||||
public static void main(String[] args)throws Exception {
|
||||
Executor executor = Executor.newInstance()
|
||||
.auth(new HttpHost("somehost"), "username", "password")
|
||||
.auth(new HttpHost("myproxy", 8080), "username", "password")
|
||||
.authPreemptive(new HttpHost("myproxy", 8080));
|
||||
|
||||
// Execute a GET with timeout settings and return response content as String.
|
||||
executor.execute(Request.Get("http://somehost/")
|
||||
.connectTimeout(1000)
|
||||
.socketTimeout(1000)
|
||||
).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.
|
||||
executor.execute(Request.Post("http://somehost/do-stuff")
|
||||
.useExpectContinue()
|
||||
.version(HttpVersion.HTTP_1_1)
|
||||
.bodyString("Important stuff", ContentType.DEFAULT_TEXT)
|
||||
).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
|
||||
executor.execute(Request.Post("http://somehost/some-form")
|
||||
.addHeader("X-Custom-header", "stuff")
|
||||
.proxy(new HttpHost("myproxy", 8080))
|
||||
.bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
|
||||
).saveContent(new File("result.dump"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.fluent;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.entity.ContentType;
|
||||
|
||||
/**
|
||||
* This example demonstrates basics of request execution with the HttpClient fluent API.
|
||||
*/
|
||||
public class FluentRequests {
|
||||
|
||||
public static void main(String[] args)throws Exception {
|
||||
// Execute a GET with timeout settings and return response content as String.
|
||||
Request.Get("http://somehost/")
|
||||
.connectTimeout(1000)
|
||||
.socketTimeout(1000)
|
||||
.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")
|
||||
.proxy(new HttpHost("myproxy", 8080))
|
||||
.bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
|
||||
.execute().saveContent(new File("result.dump"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.fluent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
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.entity.ContentType;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* This example demonstrates how the HttpClient fluent API can be used to handle HTTP responses
|
||||
* without buffering content body in memory.
|
||||
*/
|
||||
public class FluentResponseHandling {
|
||||
|
||||
public static void main(String[] args)throws Exception {
|
||||
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();
|
||||
if (charset == null) {
|
||||
charset = HTTP.DEFAULT_CONTENT_CHARSET;
|
||||
}
|
||||
return docBuilder.parse(entity.getContent(), charset);
|
||||
} catch (ParserConfigurationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
} catch (SAXException ex) {
|
||||
throw new ClientProtocolException("Malformed XML document", ex);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
// Do something useful with the result
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,8 @@ import org.apache.http.protocol.HTTP;
|
|||
|
||||
public class Content {
|
||||
|
||||
public static final Content NO_CONTENT = new Content(new byte[] {}, ContentType.DEFAULT_BINARY);
|
||||
|
||||
private final byte[] raw;
|
||||
private final ContentType type;
|
||||
|
||||
|
|
|
@ -87,8 +87,7 @@ public class Executor {
|
|||
return auth(authScope, creds);
|
||||
}
|
||||
|
||||
public Executor authPreemptive(final HttpHost host, final Credentials creds) {
|
||||
auth(host, creds);
|
||||
public Executor authPreemptive(final HttpHost host) {
|
||||
this.authCache.put(host, new BasicScheme());
|
||||
return this;
|
||||
}
|
||||
|
@ -117,13 +116,6 @@ public class Executor {
|
|||
return auth(host, new NTCredentials(username, password, workstation, domain));
|
||||
}
|
||||
|
||||
public Executor authPreemptive(final HttpHost host,
|
||||
final String username, final String password) {
|
||||
auth(host, username, password);
|
||||
this.authCache.put(host, new BasicScheme());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Executor clearAuth() {
|
||||
if (this.credentialsProvider != null) {
|
||||
this.credentialsProvider.clear();
|
||||
|
@ -143,7 +135,7 @@ public class Executor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Response exec(
|
||||
public Response execute(
|
||||
final Request req) throws ClientProtocolException, IOException {
|
||||
this.localContext.setAttribute(ClientContext.CREDS_PROVIDER, this.credentialsProvider);
|
||||
this.localContext.setAttribute(ClientContext.AUTH_CACHE, this.authCache);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.fluent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
public class Form {
|
||||
|
||||
private final List<NameValuePair> params;
|
||||
|
||||
public static Form form() {
|
||||
return new Form();
|
||||
}
|
||||
|
||||
Form() {
|
||||
super();
|
||||
this.params = new ArrayList<NameValuePair>();
|
||||
}
|
||||
|
||||
public Form add(final String name, final String value) {
|
||||
this.params.add(new BasicNameValuePair(name, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<NameValuePair> build() {
|
||||
return new ArrayList<NameValuePair>(this.params);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
package org.apache.http.client.fluent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
@ -55,6 +56,7 @@ import org.apache.http.client.methods.HttpTrace;
|
|||
import org.apache.http.conn.params.ConnRoutePNames;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.FileEntity;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.params.CoreConnectionPNames;
|
||||
|
@ -139,7 +141,7 @@ public class Request {
|
|||
return this.request;
|
||||
}
|
||||
|
||||
public Response exec() throws ClientProtocolException, IOException {
|
||||
public Response execute() throws ClientProtocolException, IOException {
|
||||
return new Response(Executor.CLIENT.execute(this.request));
|
||||
}
|
||||
|
||||
|
@ -268,35 +270,43 @@ public class Request {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Request htmlFormBody(final NameValuePair[] formParams, final String charset) {
|
||||
public Request bodyForm(final Iterable <? extends NameValuePair> formParams, final String charset) {
|
||||
try {
|
||||
return body(new UrlEncodedFormEntity(Arrays.asList(formParams)));
|
||||
return body(new UrlEncodedFormEntity(formParams));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new IllegalArgumentException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Request htmlFormBody(final NameValuePair... formParams) {
|
||||
return htmlFormBody(formParams, HTTP.DEFAULT_CONTENT_CHARSET);
|
||||
public Request bodyForm(final Iterable <? extends NameValuePair> formParams) {
|
||||
return bodyForm(formParams, HTTP.DEFAULT_CONTENT_CHARSET);
|
||||
}
|
||||
|
||||
public Request stringBody(final String s, final ContentType contentType) {
|
||||
public Request bodyForm(final NameValuePair... formParams) {
|
||||
return bodyForm(Arrays.asList(formParams), HTTP.DEFAULT_CONTENT_CHARSET);
|
||||
}
|
||||
|
||||
public Request bodyString(final String s, final ContentType contentType) {
|
||||
return body(StringEntity.create(s, contentType));
|
||||
}
|
||||
|
||||
public Request byteArrayBody(final byte[] b) {
|
||||
public Request bodyFile(final File file, final ContentType contentType) {
|
||||
return body(new FileEntity(file, contentType));
|
||||
}
|
||||
|
||||
public Request bodyByteArray(final byte[] b) {
|
||||
return body(new ByteArrayEntity(b));
|
||||
}
|
||||
|
||||
public Request byteArrayBody(final byte[] b, int off, int len) {
|
||||
public Request bodyByteArray(final byte[] b, int off, int len) {
|
||||
return body(new ByteArrayEntity(b, off, len));
|
||||
}
|
||||
|
||||
public Request streamBody(final InputStream instream) {
|
||||
public Request bodyStream(final InputStream instream) {
|
||||
return body(new InputStreamEntity(instream, -1));
|
||||
}
|
||||
|
||||
public Request streamBody(final InputStream instream, final ContentType contentType) {
|
||||
public Request bodyStream(final InputStream instream, final ContentType contentType) {
|
||||
return body(new InputStreamEntity(instream, -1, contentType));
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class Response {
|
|||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
private void dispose() {
|
||||
if (this.consumed) {
|
||||
return;
|
||||
}
|
||||
|
@ -68,7 +68,12 @@ public class Response {
|
|||
}
|
||||
}
|
||||
|
||||
public <T> T handle(final ResponseHandler<T> handler) throws ClientProtocolException, IOException {
|
||||
public void discardContent() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public <T> T handleResponse(
|
||||
final ResponseHandler<T> handler) throws ClientProtocolException, IOException {
|
||||
assertNotConsumed();
|
||||
try {
|
||||
return handler.handleResponse(this.response);
|
||||
|
@ -77,8 +82,8 @@ public class Response {
|
|||
}
|
||||
}
|
||||
|
||||
public Content content() throws ClientProtocolException, IOException {
|
||||
return handle(new ResponseHandler<Content>() {
|
||||
public Content returnContent() throws ClientProtocolException, IOException {
|
||||
return handleResponse(new ResponseHandler<Content>() {
|
||||
|
||||
public Content handleResponse(
|
||||
final HttpResponse response) throws ClientProtocolException, IOException {
|
||||
|
@ -89,17 +94,18 @@ public class Response {
|
|||
statusLine.getReasonPhrase());
|
||||
}
|
||||
if (entity != null) {
|
||||
return new Content(EntityUtils.toByteArray(entity),
|
||||
return new Content(
|
||||
EntityUtils.toByteArray(entity),
|
||||
ContentType.getOrDefault(entity));
|
||||
} else {
|
||||
return null;
|
||||
return Content.NO_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public HttpResponse response() throws IOException {
|
||||
public HttpResponse returnResponse() throws IOException {
|
||||
assertNotConsumed();
|
||||
try {
|
||||
HttpEntity entity = this.response.getEntity();
|
||||
|
@ -113,7 +119,7 @@ public class Response {
|
|||
}
|
||||
}
|
||||
|
||||
public void save(final File file) throws IOException {
|
||||
public void saveContent(final File file) throws IOException {
|
||||
assertNotConsumed();
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue