001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.client.methods; 029 030import java.io.IOException; 031import java.net.URI; 032import java.net.URISyntaxException; 033import java.nio.charset.Charset; 034import java.util.ArrayList; 035import java.util.LinkedList; 036import java.util.List; 037 038import org.apache.http.Consts; 039import org.apache.http.Header; 040import org.apache.http.HeaderIterator; 041import org.apache.http.HttpEntity; 042import org.apache.http.HttpEntityEnclosingRequest; 043import org.apache.http.HttpRequest; 044import org.apache.http.NameValuePair; 045import org.apache.http.ProtocolVersion; 046import org.apache.http.client.config.RequestConfig; 047import org.apache.http.client.entity.UrlEncodedFormEntity; 048import org.apache.http.client.utils.URIBuilder; 049import org.apache.http.client.utils.URLEncodedUtils; 050import org.apache.http.entity.ContentType; 051import org.apache.http.message.BasicHeader; 052import org.apache.http.message.BasicNameValuePair; 053import org.apache.http.message.HeaderGroup; 054import org.apache.http.protocol.HTTP; 055import org.apache.http.util.Args; 056 057/** 058 * Builder for {@link HttpUriRequest} instances. 059 * <p> 060 * Please note that this class treats parameters differently depending on composition 061 * of the request: if the request has a content entity explicitly set with 062 * {@link #setEntity(org.apache.http.HttpEntity)} or it is not an entity enclosing method 063 * (such as POST or PUT), parameters will be added to the query component of the request URI. 064 * Otherwise, parameters will be added as a URL encoded {@link UrlEncodedFormEntity entity}. 065 * </p> 066 * 067 * @since 4.3 068 */ 069public class RequestBuilder { 070 071 private String method; 072 private Charset charset; 073 private ProtocolVersion version; 074 private URI uri; 075 private HeaderGroup headergroup; 076 private HttpEntity entity; 077 private List<NameValuePair> parameters; 078 private RequestConfig config; 079 080 RequestBuilder(final String method) { 081 super(); 082 this.charset = Consts.UTF_8; 083 this.method = method; 084 } 085 086 RequestBuilder(final String method, final URI uri) { 087 super(); 088 this.method = method; 089 this.uri = uri; 090 } 091 092 RequestBuilder(final String method, final String uri) { 093 super(); 094 this.method = method; 095 this.uri = uri != null ? URI.create(uri) : null; 096 } 097 098 RequestBuilder() { 099 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}