View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.client.methods;
29  
30  import java.io.IOException;
31  import java.net.URI;
32  import java.net.URISyntaxException;
33  import java.nio.charset.Charset;
34  import java.util.ArrayList;
35  import java.util.LinkedList;
36  import java.util.List;
37  
38  import org.apache.http.Consts;
39  import org.apache.http.Header;
40  import org.apache.http.HeaderIterator;
41  import org.apache.http.HttpEntity;
42  import org.apache.http.HttpEntityEnclosingRequest;
43  import org.apache.http.HttpRequest;
44  import org.apache.http.NameValuePair;
45  import org.apache.http.ProtocolVersion;
46  import org.apache.http.annotation.NotThreadSafe;
47  import org.apache.http.client.config.RequestConfig;
48  import org.apache.http.client.entity.UrlEncodedFormEntity;
49  import org.apache.http.client.utils.URIBuilder;
50  import org.apache.http.client.utils.URLEncodedUtils;
51  import org.apache.http.entity.ContentType;
52  import org.apache.http.message.BasicHeader;
53  import org.apache.http.message.BasicNameValuePair;
54  import org.apache.http.message.HeaderGroup;
55  import org.apache.http.protocol.HTTP;
56  import org.apache.http.util.Args;
57  
58  /**
59   * Builder for {@link HttpUriRequest} instances.
60   * <p>
61   * Please note that this class treats parameters differently depending on composition
62   * of the request: if the request has a content entity explicitly set with
63   * {@link #setEntity(org.apache.http.HttpEntity)} or it is not an entity enclosing method
64   * (such as POST or PUT), parameters will be added to the query component of the request URI.
65   * Otherwise, parameters will be added as a URL encoded {@link UrlEncodedFormEntity entity}.
66   * </p>
67   *
68   * @since 4.3
69   */
70  @NotThreadSafe
71  public class RequestBuilder {
72  
73      private String method;
74      private Charset charset;
75      private ProtocolVersion version;
76      private URI uri;
77      private HeaderGroup headergroup;
78      private HttpEntity entity;
79      private List<NameValuePair> parameters;
80      private RequestConfig config;
81  
82      RequestBuilder(final String method) {
83          super();
84          this.charset = Consts.UTF_8;
85          this.method = method;
86      }
87  
88      RequestBuilder(final String method, final URI uri) {
89          super();
90          this.method = method;
91          this.uri = uri;
92      }
93  
94      RequestBuilder(final String method, final String uri) {
95          super();
96          this.method = method;
97          this.uri = uri != null ? URI.create(uri) : null;
98      }
99  
100     RequestBuilder() {
101         this(null);
102     }
103 
104     public static RequestBuilder create(final String method) {
105         Args.notBlank(method, "HTTP method");
106         return new RequestBuilder(method);
107     }
108 
109     public static RequestBuilder get() {
110         return new RequestBuilder(HttpGet.METHOD_NAME);
111     }
112 
113     /**
114      * @since 4.4
115      */
116     public static RequestBuilder get(final URI uri) {
117         return new RequestBuilder(HttpGet.METHOD_NAME, uri);
118     }
119 
120     /**
121      * @since 4.4
122      */
123     public static RequestBuilder get(final String uri) {
124         return new RequestBuilder(HttpGet.METHOD_NAME, uri);
125     }
126 
127     public static RequestBuilder head() {
128         return new RequestBuilder(HttpHead.METHOD_NAME);
129     }
130 
131     /**
132      * @since 4.4
133      */
134     public static RequestBuilder head(final URI uri) {
135         return new RequestBuilder(HttpHead.METHOD_NAME, uri);
136     }
137 
138     /**
139      * @since 4.4
140      */
141     public static RequestBuilder head(final String uri) {
142         return new RequestBuilder(HttpHead.METHOD_NAME, uri);
143     }
144 
145     public static RequestBuilder post() {
146         return new RequestBuilder(HttpPost.METHOD_NAME);
147     }
148 
149     /**
150      * @since 4.4
151      */
152     public static RequestBuilder post(final URI uri) {
153         return new RequestBuilder(HttpPost.METHOD_NAME, uri);
154     }
155 
156     /**
157      * @since 4.4
158      */
159     public static RequestBuilder post(final String uri) {
160         return new RequestBuilder(HttpPost.METHOD_NAME, uri);
161     }
162 
163     public static RequestBuilder put() {
164         return new RequestBuilder(HttpPut.METHOD_NAME);
165     }
166 
167     /**
168      * @since 4.4
169      */
170     public static RequestBuilder put(final URI uri) {
171         return new RequestBuilder(HttpPut.METHOD_NAME, uri);
172     }
173 
174     /**
175      * @since 4.4
176      */
177     public static RequestBuilder put(final String uri) {
178         return new RequestBuilder(HttpPut.METHOD_NAME, uri);
179     }
180 
181     public static RequestBuilder delete() {
182         return new RequestBuilder(HttpDelete.METHOD_NAME);
183     }
184 
185     /**
186      * @since 4.4
187      */
188     public static RequestBuilder delete(final URI uri) {
189         return new RequestBuilder(HttpDelete.METHOD_NAME, uri);
190     }
191 
192     /**
193      * @since 4.4
194      */
195     public static RequestBuilder delete(final String uri) {
196         return new RequestBuilder(HttpDelete.METHOD_NAME, uri);
197     }
198 
199     public static RequestBuilder trace() {
200         return new RequestBuilder(HttpTrace.METHOD_NAME);
201     }
202 
203     /**
204      * @since 4.4
205      */
206     public static RequestBuilder trace(final URI uri) {
207         return new RequestBuilder(HttpTrace.METHOD_NAME, uri);
208     }
209 
210     /**
211      * @since 4.4
212      */
213     public static RequestBuilder trace(final String uri) {
214         return new RequestBuilder(HttpTrace.METHOD_NAME, uri);
215     }
216 
217     public static RequestBuilder options() {
218         return new RequestBuilder(HttpOptions.METHOD_NAME);
219     }
220 
221     /**
222      * @since 4.4
223      */
224     public static RequestBuilder options(final URI uri) {
225         return new RequestBuilder(HttpOptions.METHOD_NAME, uri);
226     }
227 
228     /**
229      * @since 4.4
230      */
231     public static RequestBuilder options(final String uri) {
232         return new RequestBuilder(HttpOptions.METHOD_NAME, uri);
233     }
234 
235     public static RequestBuilder copy(final HttpRequest request) {
236         Args.notNull(request, "HTTP request");
237         return new RequestBuilder().doCopy(request);
238     }
239 
240     private RequestBuilder doCopy(final HttpRequest request) {
241         if (request == null) {
242             return this;
243         }
244         method = request.getRequestLine().getMethod();
245         version = request.getRequestLine().getProtocolVersion();
246 
247         if (headergroup == null) {
248             headergroup = new HeaderGroup();
249         }
250         headergroup.clear();
251         headergroup.setHeaders(request.getAllHeaders());
252 
253         parameters = null;
254         entity = null;
255 
256         if (request instanceof HttpEntityEnclosingRequest) {
257             final HttpEntity originalEntity = ((HttpEntityEnclosingRequest) request).getEntity();
258             final ContentType contentType = ContentType.get(originalEntity);
259             if (contentType != null &&
260                     contentType.getMimeType().equals(ContentType.APPLICATION_FORM_URLENCODED.getMimeType())) {
261                 try {
262                     final List<NameValuePair> formParams = URLEncodedUtils.parse(originalEntity);
263                     if (!formParams.isEmpty()) {
264                         parameters = formParams;
265                     }
266                 } catch (IOException ignore) {
267                 }
268             } else {
269                 entity = originalEntity;
270             }
271         }
272 
273         final URI originalUri;
274         if (request instanceof HttpUriRequest) {
275             originalUri = ((HttpUriRequest) request).getURI();
276         } else {
277             originalUri = URI.create(request.getRequestLine().getUri());
278         }
279 
280         final URIBuilder uriBuilder = new URIBuilder(originalUri);
281         if (parameters == null) {
282             final List<NameValuePair> queryParams = uriBuilder.getQueryParams();
283             if (!queryParams.isEmpty()) {
284                 parameters = queryParams;
285                 uriBuilder.clearParameters();
286             } else {
287                 parameters = null;
288             }
289         }
290         try {
291             uri = uriBuilder.build();
292         } catch (URISyntaxException ex) {
293             // Should never happen
294             uri = originalUri;
295         }
296 
297         if (request instanceof Configurable) {
298             config = ((Configurable) request).getConfig();
299         } else {
300             config = null;
301         }
302         return this;
303     }
304 
305     /**
306      * @since 4.4
307      */
308     public RequestBuilder setCharset(final Charset charset) {
309         this.charset = charset;
310         return this;
311     }
312 
313     /**
314      * @since 4.4
315      */
316     public Charset getCharset() {
317         return charset;
318     }
319 
320     public String getMethod() {
321         return method;
322     }
323 
324     public ProtocolVersion getVersion() {
325         return version;
326     }
327 
328     public RequestBuilder setVersion(final ProtocolVersion version) {
329         this.version = version;
330         return this;
331     }
332 
333     public URI getUri() {
334         return uri;
335     }
336 
337     public RequestBuilder setUri(final URI uri) {
338         this.uri = uri;
339         return this;
340     }
341 
342     public RequestBuilder setUri(final String uri) {
343         this.uri = uri != null ? URI.create(uri) : null;
344         return this;
345     }
346 
347     public Header getFirstHeader(final String name) {
348         return headergroup != null ? headergroup.getFirstHeader(name) : null;
349     }
350 
351     public Header getLastHeader(final String name) {
352         return headergroup != null ? headergroup.getLastHeader(name) : null;
353     }
354 
355     public Header[] getHeaders(final String name) {
356         return headergroup != null ? headergroup.getHeaders(name) : null;
357     }
358 
359     public RequestBuilder addHeader(final Header header) {
360         if (headergroup == null) {
361             headergroup = new HeaderGroup();
362         }
363         headergroup.addHeader(header);
364         return this;
365     }
366 
367     public RequestBuilder addHeader(final String name, final String value) {
368         if (headergroup == null) {
369             headergroup = new HeaderGroup();
370         }
371         this.headergroup.addHeader(new BasicHeader(name, value));
372         return this;
373     }
374 
375     public RequestBuilder removeHeader(final Header header) {
376         if (headergroup == null) {
377             headergroup = new HeaderGroup();
378         }
379         headergroup.removeHeader(header);
380         return this;
381     }
382 
383     public RequestBuilder removeHeaders(final String name) {
384         if (name == null || headergroup == null) {
385             return this;
386         }
387         for (final HeaderIterator i = headergroup.iterator(); i.hasNext(); ) {
388             final Header header = i.nextHeader();
389             if (name.equalsIgnoreCase(header.getName())) {
390                 i.remove();
391             }
392         }
393         return this;
394     }
395 
396     public RequestBuilder setHeader(final Header header) {
397         if (headergroup == null) {
398             headergroup = new HeaderGroup();
399         }
400         this.headergroup.updateHeader(header);
401         return this;
402     }
403 
404     public RequestBuilder setHeader(final String name, final String value) {
405         if (headergroup == null) {
406             headergroup = new HeaderGroup();
407         }
408         this.headergroup.updateHeader(new BasicHeader(name, value));
409         return this;
410     }
411 
412     public HttpEntity getEntity() {
413         return entity;
414     }
415 
416     public RequestBuilder setEntity(final HttpEntity entity) {
417         this.entity = entity;
418         return this;
419     }
420 
421     public List<NameValuePair> getParameters() {
422         return parameters != null ? new ArrayList<NameValuePair>(parameters) :
423             new ArrayList<NameValuePair>();
424     }
425 
426     public RequestBuilder addParameter(final NameValuePair nvp) {
427         Args.notNull(nvp, "Name value pair");
428         if (parameters == null) {
429             parameters = new LinkedList<NameValuePair>();
430         }
431         parameters.add(nvp);
432         return this;
433     }
434 
435     public RequestBuilder addParameter(final String name, final String value) {
436         return addParameter(new BasicNameValuePair(name, value));
437     }
438 
439     public RequestBuilder addParameters(final NameValuePair... nvps) {
440         for (final NameValuePair nvp: nvps) {
441             addParameter(nvp);
442         }
443         return this;
444     }
445 
446     public RequestConfig getConfig() {
447         return config;
448     }
449 
450     public RequestBuilder setConfig(final RequestConfig config) {
451         this.config = config;
452         return this;
453     }
454 
455     public HttpUriRequest build() {
456         final HttpRequestBase result;
457         URI uriNotNull = this.uri != null ? this.uri : URI.create("/");
458         HttpEntity entityCopy = this.entity;
459         if (parameters != null && !parameters.isEmpty()) {
460             if (entityCopy == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method)
461                     || HttpPut.METHOD_NAME.equalsIgnoreCase(method))) {
462                 entityCopy = new UrlEncodedFormEntity(parameters, HTTP.DEF_CONTENT_CHARSET);
463             } else {
464                 try {
465                     uriNotNull = new URIBuilder(uriNotNull)
466                       .setCharset(this.charset)
467                       .addParameters(parameters)
468                       .build();
469                 } catch (final URISyntaxException ex) {
470                     // should never happen
471                 }
472             }
473         }
474         if (entityCopy == null) {
475             result = new InternalRequest(method);
476         } else {
477             final InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(method);
478             request.setEntity(entityCopy);
479             result = request;
480         }
481         result.setProtocolVersion(this.version);
482         result.setURI(uriNotNull);
483         if (this.headergroup != null) {
484             result.setHeaders(this.headergroup.getAllHeaders());
485         }
486         result.setConfig(this.config);
487         return result;
488     }
489 
490     static class InternalRequest extends HttpRequestBase {
491 
492         private final String method;
493 
494         InternalRequest(final String method) {
495             super();
496             this.method = method;
497         }
498 
499         @Override
500         public String getMethod() {
501             return this.method;
502         }
503 
504     }
505 
506     static class InternalEntityEclosingRequest extends HttpEntityEnclosingRequestBase {
507 
508         private final String method;
509 
510         InternalEntityEclosingRequest(final String method) {
511             super();
512             this.method = method;
513         }
514 
515         @Override
516         public String getMethod() {
517             return this.method;
518         }
519 
520     }
521 
522 }