HTTPCLIENT-1253: RequestBuilder to support request parameters that can be transmitted either in the request body or in the request URI depending on composition of the request

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1426353 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2012-12-27 22:26:53 +00:00
parent 9c0a28cd6c
commit 9d3171f15e
3 changed files with 143 additions and 72 deletions

View File

@ -28,18 +28,27 @@
package org.apache.http.client.methods;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.ProtocolVersion;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.utils.CloneUtils;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.message.HeaderGroup;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.Args;
/**
* @since 4.3
@ -52,6 +61,7 @@ public class RequestBuilder {
private URI uri;
private HeaderGroup headergroup;
private HttpEntity entity;
private LinkedList<NameValuePair> parameters;
private RequestConfig config;
RequestBuilder(final String method) {
@ -64,45 +74,43 @@ public class RequestBuilder {
}
public static RequestBuilder create(final String method) {
Args.notBlank(method, "HTTP method");
return new RequestBuilder(method);
}
public static RequestBuilder createGet() {
public static RequestBuilder get() {
return new RequestBuilder(HttpGet.METHOD_NAME);
}
public static RequestBuilder createHead() {
public static RequestBuilder head() {
return new RequestBuilder(HttpHead.METHOD_NAME);
}
public static RequestBuilder createPost() {
public static RequestBuilder post() {
return new RequestBuilder(HttpPost.METHOD_NAME);
}
public static RequestBuilder createPut() {
public static RequestBuilder put() {
return new RequestBuilder(HttpPut.METHOD_NAME);
}
public static RequestBuilder createDelete() {
public static RequestBuilder delete() {
return new RequestBuilder(HttpDelete.METHOD_NAME);
}
public static RequestBuilder createTrace() {
public static RequestBuilder trace() {
return new RequestBuilder(HttpTrace.METHOD_NAME);
}
public static RequestBuilder createOptions() {
public static RequestBuilder options() {
return new RequestBuilder(HttpOptions.METHOD_NAME);
}
public static RequestBuilder copy(final HttpRequest request) {
Args.notNull(request, "HTTP request");
return new RequestBuilder().doCopy(request);
}
public static RequestBuilder clone(final HttpRequest request) throws CloneNotSupportedException {
return new RequestBuilder().doCopy(CloneUtils.cloneObject(request));
}
private RequestBuilder doCopy(final HttpRequest request) {
if (request == null) {
return this;
@ -129,6 +137,7 @@ public class RequestBuilder {
} else {
this.config = null;
}
this.parameters = null;
return this;
}
@ -136,11 +145,6 @@ public class RequestBuilder {
return method;
}
public RequestBuilder setMethod(final String method) {
this.method = method;
return this;
}
public ProtocolVersion getVersion() {
return version;
}
@ -238,6 +242,31 @@ public class RequestBuilder {
return this;
}
public List<NameValuePair> getParameters() {
return parameters != null ? new ArrayList<NameValuePair>(parameters) :
new ArrayList<NameValuePair>();
}
public RequestBuilder addParameter(final NameValuePair nvp) {
Args.notNull(nvp, "Name value pair");
if (parameters == null) {
parameters = new LinkedList<NameValuePair>();
}
parameters.add(nvp);
return this;
}
public RequestBuilder addParameter(final String name, final String value) {
return addParameter(new BasicNameValuePair(name, value));
}
public RequestBuilder addParameters(final NameValuePair... nvps) {
for (NameValuePair nvp: nvps) {
addParameter(nvp);
}
return this;
}
public RequestConfig getConfig() {
return config;
}
@ -247,24 +276,32 @@ public class RequestBuilder {
return this;
}
private String getMethodName() {
return this.method != null ? this.method :
(this.entity != null ? HttpPost.METHOD_NAME : HttpGet.METHOD_NAME);
}
public HttpUriRequest build() {
HttpRequestBase result;
String methodName = getMethodName();
if (this.entity == null) {
InternalRequest request = new InternalRequest(methodName);
URI uri = this.uri != null ? this.uri : URI.create("/");
HttpEntity entity = this.entity;
if (parameters != null && !parameters.isEmpty()) {
if (entity == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method)
|| HttpPut.METHOD_NAME.equalsIgnoreCase(method))) {
entity = new UrlEncodedFormEntity(parameters, HTTP.DEF_CONTENT_CHARSET);
} else {
try {
uri = new URIBuilder(uri).addParameters(parameters).build();
} catch (URISyntaxException ex) {
// should never happen
}
}
}
if (entity == null) {
InternalRequest request = new InternalRequest(method);
result = request;
} else {
InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(methodName);
request.setEntity(this.entity);
InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(method);
request.setEntity(entity);
result = request;
}
result.setProtocolVersion(this.version);
result.setURI(this.uri != null ? this.uri : URI.create("/"));
result.setURI(uri);
if (this.headergroup != null) {
result.setHeaders(this.headergroup.getAllHeaders());
}

View File

@ -292,6 +292,26 @@ public class URIBuilder {
return this;
}
/**
* Adds URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
* <p/>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
*
* @since 4.3
*/
public URIBuilder addParameters(final List <NameValuePair> nvps) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<NameValuePair>();
}
this.queryParams.addAll(nvps);
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Sets URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.

View File

@ -37,6 +37,8 @@ import org.apache.http.client.config.RequestConfig;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Assert;
import org.junit.Test;
@ -44,7 +46,7 @@ public class TestRequestBuilder {
@Test
public void testBasicGet() throws Exception {
HttpUriRequest request = RequestBuilder.createGet().build();
HttpUriRequest request = RequestBuilder.get().build();
Assert.assertNotNull(request);
Assert.assertEquals("GET", request.getMethod());
Assert.assertEquals(URI.create("/"), request.getURI());
@ -64,7 +66,7 @@ public class TestRequestBuilder {
@Test
public void testBasicWithEntity() throws Exception {
HttpEntity entity = new BasicHttpEntity();
HttpUriRequest request = RequestBuilder.createPost().setEntity(entity).build();
HttpUriRequest request = RequestBuilder.post().setEntity(entity).build();
Assert.assertNotNull(request);
Assert.assertEquals("POST", request.getMethod());
Assert.assertEquals(URI.create("/"), request.getURI());
@ -76,7 +78,7 @@ public class TestRequestBuilder {
@Test
public void testGetWithEntity() throws Exception {
HttpEntity entity = new BasicHttpEntity();
HttpUriRequest request = RequestBuilder.createGet().setEntity(entity).build();
HttpUriRequest request = RequestBuilder.get().setEntity(entity).build();
Assert.assertNotNull(request);
Assert.assertEquals("GET", request.getMethod());
Assert.assertEquals(URI.create("/"), request.getURI());
@ -85,11 +87,56 @@ public class TestRequestBuilder {
Assert.assertSame(entity, ((HttpEntityEnclosingRequest) request).getEntity());
}
@Test
public void testAddParameters1() throws Exception {
HttpUriRequest request = RequestBuilder.get()
.addParameter("p1", "this")
.addParameter("p2", "that")
.build();
Assert.assertFalse(request instanceof HttpEntityEnclosingRequest);
Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getURI());
}
@Test
public void testAddParameters2() throws Exception {
HttpUriRequest request = RequestBuilder.get()
.addParameter("p1", "this")
.addParameters(new BasicNameValuePair("p2", "that"))
.build();
Assert.assertFalse(request instanceof HttpEntityEnclosingRequest);
Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getURI());
}
@Test
public void testAddParameters3() throws Exception {
HttpUriRequest request = RequestBuilder.post()
.addParameter("p1", "this")
.addParameter("p2", "that")
.build();
Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
Assert.assertNotNull(entity);
Assert.assertEquals(new URI("/"), request.getURI());
Assert.assertEquals("p1=this&p2=that", EntityUtils.toString(entity));
}
@Test
public void testAddParameters4() throws Exception {
HttpUriRequest request = RequestBuilder.post()
.setUri("http://targethost/?blah")
.addParameter("p1", "this")
.addParameter("p2", "that")
.setEntity(new StringEntity("blah"))
.build();
Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
Assert.assertEquals(new URI("http://targethost/?blah&p1=this&p2=that"), request.getURI());
}
@Test
public void testCopy() throws Exception {
HttpEntity entity = new StringEntity("stuff");
RequestConfig config = RequestConfig.custom().build();
HttpUriRequest request = RequestBuilder.createPut()
HttpUriRequest request = RequestBuilder.put()
.setUri(URI.create("/stuff"))
.setVersion(HttpVersion.HTTP_1_0)
.addHeader("header1", "stuff")
@ -112,49 +159,13 @@ public class TestRequestBuilder {
Assert.assertSame(config, ((Configurable) copy).getConfig());
}
@Test
public void testClone() throws Exception {
HttpEntity entity = new StringEntity("stuff");
RequestConfig config = RequestConfig.custom().build();
HttpUriRequest request = RequestBuilder.createPut()
.setUri(URI.create("/stuff"))
.setVersion(HttpVersion.HTTP_1_0)
.addHeader("header1", "stuff")
.setHeader("header2", "more stuff")
.setEntity(entity)
.setConfig(config)
.build();
Assert.assertNotNull(request);
Assert.assertEquals("PUT", request.getMethod());
Assert.assertEquals(URI.create("/stuff"), request.getURI());
Assert.assertEquals(HttpVersion.HTTP_1_0, request.getProtocolVersion());
Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
HttpUriRequest clone = RequestBuilder.clone(request).setUri("/other-stuff").build();
Assert.assertEquals("PUT", clone.getMethod());
Assert.assertEquals(URI.create("/other-stuff"), clone.getURI());
Assert.assertTrue(clone instanceof HttpEntityEnclosingRequest);
Assert.assertNotNull(((HttpEntityEnclosingRequest) clone).getEntity());
Assert.assertNotSame(entity, ((HttpEntityEnclosingRequest) clone).getEntity());
Assert.assertTrue(clone instanceof Configurable);
Assert.assertSame(config, ((Configurable) clone).getConfig());
}
@Test
public void testCopyNull() throws Exception {
HttpUriRequest copy = RequestBuilder.copy(null).setUri("/other-stuff").build();
Assert.assertEquals("GET", copy.getMethod());
Assert.assertEquals(URI.create("/other-stuff"), copy.getURI());
Assert.assertFalse(copy instanceof HttpEntityEnclosingRequest);
}
@Test
public void testGettersAndMutators() throws Exception {
HttpEntity entity = new StringEntity("stuff");
RequestConfig config = RequestConfig.custom().build();
Header h1 = new BasicHeader("header1", "stuff");
Header h2 = new BasicHeader("header1", "more-stuff");
RequestBuilder builder = RequestBuilder.createPut()
RequestBuilder builder = RequestBuilder.put()
.setUri("/stuff")
.setVersion(HttpVersion.HTTP_1_0)
.addHeader(h1)
@ -170,15 +181,13 @@ public class TestRequestBuilder {
Assert.assertSame(entity, builder.getEntity());
Assert.assertSame(config, builder.getConfig());
builder.setMethod(null)
.setUri((String) null)
builder.setUri((String) null)
.setVersion(null)
.removeHeader(h1)
.removeHeaders("header1")
.removeHeader(h2)
.setEntity(null)
.setConfig(null);
Assert.assertEquals(null, builder.getMethod());
Assert.assertEquals(null, builder.getUri());
Assert.assertEquals(null, builder.getVersion());
Assert.assertSame(null, builder.getFirstHeader("header1"));
@ -188,4 +197,9 @@ public class TestRequestBuilder {
Assert.assertSame(null, builder.getConfig());
}
@Test(expected=IllegalArgumentException.class)
public void testCopyNull() throws Exception {
RequestBuilder.copy(null);
}
}