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     /**
146      * @since 4.4
147      */
148     public static RequestBuilder patch() {
149         return new RequestBuilder(HttpPatch.METHOD_NAME);
150     }
151 
152     /**
153      * @since 4.4
154      */
155     public static RequestBuilder patch(final URI uri) {
156         return new RequestBuilder(HttpPatch.METHOD_NAME, uri);
157     }
158 
159     /**
160      * @since 4.4
161      */
162     public static RequestBuilder patch(final String uri) {
163         return new RequestBuilder(HttpPatch.METHOD_NAME, uri);
164     }
165 
166     public static RequestBuilder post() {
167         return new RequestBuilder(HttpPost.METHOD_NAME);
168     }
169 
170     /**
171      * @since 4.4
172      */
173     public static RequestBuilder post(final URI uri) {
174         return new RequestBuilder(HttpPost.METHOD_NAME, uri);
175     }
176 
177     /**
178      * @since 4.4
179      */
180     public static RequestBuilder post(final String uri) {
181         return new RequestBuilder(HttpPost.METHOD_NAME, uri);
182     }
183 
184     public static RequestBuilder put() {
185         return new RequestBuilder(HttpPut.METHOD_NAME);
186     }
187 
188     /**
189      * @since 4.4
190      */
191     public static RequestBuilder put(final URI uri) {
192         return new RequestBuilder(HttpPut.METHOD_NAME, uri);
193     }
194 
195     /**
196      * @since 4.4
197      */
198     public static RequestBuilder put(final String uri) {
199         return new RequestBuilder(HttpPut.METHOD_NAME, uri);
200     }
201 
202     public static RequestBuilder delete() {
203         return new RequestBuilder(HttpDelete.METHOD_NAME);
204     }
205 
206     /**
207      * @since 4.4
208      */
209     public static RequestBuilder delete(final URI uri) {
210         return new RequestBuilder(HttpDelete.METHOD_NAME, uri);
211     }
212 
213     /**
214      * @since 4.4
215      */
216     public static RequestBuilder delete(final String uri) {
217         return new RequestBuilder(HttpDelete.METHOD_NAME, uri);
218     }
219 
220     public static RequestBuilder trace() {
221         return new RequestBuilder(HttpTrace.METHOD_NAME);
222     }
223 
224     /**
225      * @since 4.4
226      */
227     public static RequestBuilder trace(final URI uri) {
228         return new RequestBuilder(HttpTrace.METHOD_NAME, uri);
229     }
230 
231     /**
232      * @since 4.4
233      */
234     public static RequestBuilder trace(final String uri) {
235         return new RequestBuilder(HttpTrace.METHOD_NAME, uri);
236     }
237 
238     public static RequestBuilder options() {
239         return new RequestBuilder(HttpOptions.METHOD_NAME);
240     }
241 
242     /**
243      * @since 4.4
244      */
245     public static RequestBuilder options(final URI uri) {
246         return new RequestBuilder(HttpOptions.METHOD_NAME, uri);
247     }
248 
249     /**
250      * @since 4.4
251      */
252     public static RequestBuilder options(final String uri) {
253         return new RequestBuilder(HttpOptions.METHOD_NAME, uri);
254     }
255 
256     public static RequestBuilder copy(final HttpRequest request) {
257         Args.notNull(request, "HTTP request");
258         return new RequestBuilder().doCopy(request);
259     }
260 
261     private RequestBuilder doCopy(final HttpRequest request) {
262         if (request == null) {
263             return this;
264         }
265         method = request.getRequestLine().getMethod();
266         version = request.getRequestLine().getProtocolVersion();
267 
268         if (headergroup == null) {
269             headergroup = new HeaderGroup();
270         }
271         headergroup.clear();
272         headergroup.setHeaders(request.getAllHeaders());
273 
274         parameters = null;
275         entity = null;
276 
277         if (request instanceof HttpEntityEnclosingRequest) {
278             final HttpEntity originalEntity = ((HttpEntityEnclosingRequest) request).getEntity();
279             final ContentType contentType = ContentType.get(originalEntity);
280             if (contentType != null &&
281                     contentType.getMimeType().equals(ContentType.APPLICATION_FORM_URLENCODED.getMimeType())) {
282                 try {
283                     final List<NameValuePair> formParams = URLEncodedUtils.parse(originalEntity);
284                     if (!formParams.isEmpty()) {
285                         parameters = formParams;
286                     }
287                 } catch (final IOException ignore) {
288                 }
289             } else {
290                 entity = originalEntity;
291             }
292         }
293 
294         final URI originalUri;
295         if (request instanceof HttpUriRequest) {
296             uri = ((HttpUriRequest) request).getURI();
297         } else {
298             uri = URI.create(request.getRequestLine().getUri());
299         }
300 
301         if (request instanceof Configurable) {
302             config = ((Configurable) request).getConfig();
303         } else {
304             config = null;
305         }
306         return this;
307     }
308 
309     /**
310      * @since 4.4
311      */
312     public RequestBuilder setCharset(final Charset charset) {
313         this.charset = charset;
314         return this;
315     }
316 
317     /**
318      * @since 4.4
319      */
320     public Charset getCharset() {
321         return charset;
322     }
323 
324     public String getMethod() {
325         return method;
326     }
327 
328     public ProtocolVersion getVersion() {
329         return version;
330     }
331 
332     public RequestBuilder setVersion(final ProtocolVersion version) {
333         this.version = version;
334         return this;
335     }
336 
337     public URI getUri() {
338         return uri;
339     }
340 
341     public RequestBuilder setUri(final URI uri) {
342         this.uri = uri;
343         return this;
344     }
345 
346     public RequestBuilder setUri(final String uri) {
347         this.uri = uri != null ? URI.create(uri) : null;
348         return this;
349     }
350 
351     public Header getFirstHeader(final String name) {
352         return headergroup != null ? headergroup.getFirstHeader(name) : null;
353     }
354 
355     public Header getLastHeader(final String name) {
356         return headergroup != null ? headergroup.getLastHeader(name) : null;
357     }
358 
359     public Header[] getHeaders(final String name) {
360         return headergroup != null ? headergroup.getHeaders(name) : null;
361     }
362 
363     public RequestBuilder addHeader(final Header header) {
364         if (headergroup == null) {
365             headergroup = new HeaderGroup();
366         }
367         headergroup.addHeader(header);
368         return this;
369     }
370 
371     public RequestBuilder addHeader(final String name, final String value) {
372         if (headergroup == null) {
373             headergroup = new HeaderGroup();
374         }
375         this.headergroup.addHeader(new BasicHeader(name, value));
376         return this;
377     }
378 
379     public RequestBuilder removeHeader(final Header header) {
380         if (headergroup == null) {
381             headergroup = new HeaderGroup();
382         }
383         headergroup.removeHeader(header);
384         return this;
385     }
386 
387     public RequestBuilder removeHeaders(final String name) {
388         if (name == null || headergroup == null) {
389             return this;
390         }
391         for (final HeaderIterator i = headergroup.iterator(); i.hasNext(); ) {
392             final Header header = i.nextHeader();
393             if (name.equalsIgnoreCase(header.getName())) {
394                 i.remove();
395             }
396         }
397         return this;
398     }
399 
400     public RequestBuilder setHeader(final Header header) {
401         if (headergroup == null) {
402             headergroup = new HeaderGroup();
403         }
404         this.headergroup.updateHeader(header);
405         return this;
406     }
407 
408     public RequestBuilder setHeader(final String name, final String value) {
409         if (headergroup == null) {
410             headergroup = new HeaderGroup();
411         }
412         this.headergroup.updateHeader(new BasicHeader(name, value));
413         return this;
414     }
415 
416     public HttpEntity getEntity() {
417         return entity;
418     }
419 
420     public RequestBuilder setEntity(final HttpEntity entity) {
421         this.entity = entity;
422         return this;
423     }
424 
425     public List<NameValuePair> getParameters() {
426         return parameters != null ? new ArrayList<NameValuePair>(parameters) :
427             new ArrayList<NameValuePair>();
428     }
429 
430     public RequestBuilder addParameter(final NameValuePair nvp) {
431         Args.notNull(nvp, "Name value pair");
432         if (parameters == null) {
433             parameters = new LinkedList<NameValuePair>();
434         }
435         parameters.add(nvp);
436         return this;
437     }
438 
439     public RequestBuilder addParameter(final String name, final String value) {
440         return addParameter(new BasicNameValuePair(name, value));
441     }
442 
443     public RequestBuilder addParameters(final NameValuePair... nvps) {
444         for (final NameValuePair nvp: nvps) {
445             addParameter(nvp);
446         }
447         return this;
448     }
449 
450     public RequestConfig getConfig() {
451         return config;
452     }
453 
454     public RequestBuilder setConfig(final RequestConfig config) {
455         this.config = config;
456         return this;
457     }
458 
459     public HttpUriRequest build() {
460         final HttpRequestBase result;
461         URI uriNotNull = this.uri != null ? this.uri : URI.create("/");
462         HttpEntity entityCopy = this.entity;
463         if (parameters != null && !parameters.isEmpty()) {
464             if (entityCopy == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method)
465                     || HttpPut.METHOD_NAME.equalsIgnoreCase(method))) {
466                 entityCopy = new UrlEncodedFormEntity(parameters, charset != null ? charset : HTTP.DEF_CONTENT_CHARSET);
467             } else {
468                 try {
469                     uriNotNull = new URIBuilder(uriNotNull)
470                       .setCharset(this.charset)
471                       .addParameters(parameters)
472                       .build();
473                 } catch (final URISyntaxException ex) {
474                     // should never happen
475                 }
476             }
477         }
478         if (entityCopy == null) {
479             result = new InternalRequest(method);
480         } else {
481             final InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(method);
482             request.setEntity(entityCopy);
483             result = request;
484         }
485         result.setProtocolVersion(this.version);
486         result.setURI(uriNotNull);
487         if (this.headergroup != null) {
488             result.setHeaders(this.headergroup.getAllHeaders());
489         }
490         result.setConfig(this.config);
491         return result;
492     }
493 
494     static class InternalRequest extends HttpRequestBase {
495 
496         private final String method;
497 
498         InternalRequest(final String method) {
499             super();
500             this.method = method;
501         }
502 
503         @Override
504         public String getMethod() {
505             return this.method;
506         }
507 
508     }
509 
510     static class InternalEntityEclosingRequest extends HttpEntityEnclosingRequestBase {
511 
512         private final String method;
513 
514         InternalEntityEclosingRequest(final String method) {
515             super();
516             this.method = method;
517         }
518 
519         @Override
520         public String getMethod() {
521             return this.method;
522         }
523 
524     }
525 
526 }