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