View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java,v 1.45.2.3 2003/09/12 07:33:20 olegk Exp $ 3 * $Revision: 1.45.2.3 $ 4 * $Date: 2003/09/12 07:33:20 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>. 59 * 60 * [Additional notices, if required by prior licensing conditions] 61 * 62 */ 63 package org.apache.commons.httpclient.methods; 64 65 import java.io.IOException; 66 import java.util.Iterator; 67 import java.util.Vector; 68 69 import org.apache.commons.httpclient.HttpConnection; 70 import org.apache.commons.httpclient.HttpConstants; 71 import org.apache.commons.httpclient.HttpException; 72 import org.apache.commons.httpclient.HttpState; 73 import org.apache.commons.httpclient.NameValuePair; 74 import org.apache.commons.httpclient.util.EncodingUtil; 75 import org.apache.commons.logging.Log; 76 import org.apache.commons.logging.LogFactory; 77 78 /*** 79 * Implements the HTTP POST method. 80 * <p> 81 * The HTTP POST method is defined in section 9.5 of 82 * <a href="http://www.ietf.org/rfc/rfc1945.txt">RFC1945</a>: 83 * <blockquote> 84 * The POST method is used to request that the origin server accept the entity 85 * enclosed in the request as a new subordinate of the resource identified by 86 * the Request-URI in the Request-Line. POST is designed to allow a uniform 87 * method to cover the following functions: 88 * <ul> 89 * <li>Annotation of existing resources</li> 90 * <li>Posting a message to a bulletin board, newsgroup, mailing list, or 91 * similar group of articles</li> 92 * <li>Providing a block of data, such as the result of submitting a form, 93 * to a data-handling process</li> 94 * <li>Extending a database through an append operation</li> 95 * </ul> 96 * </blockquote> 97 * </p> 98 * 99 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a> 100 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a> 101 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> 102 * @author Ortwin Gl�ck 103 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 104 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 105 * 106 * @version $Revision: 1.45.2.3 $ 107 * @since 1.0 108 */ 109 public class PostMethod extends EntityEnclosingMethod { 110 // -------------------------------------------------------------- Constants 111 112 /*** Log object for this class. */ 113 private static final Log LOG = LogFactory.getLog(PostMethod.class); 114 115 /*** The Content-Type for www-form-urlencoded. */ 116 public static final String FORM_URL_ENCODED_CONTENT_TYPE = 117 "application/x-www-form-urlencoded"; 118 119 /*** 120 * The buffered request body consisting of <code>NameValuePair</code>s. 121 */ 122 private Vector params = new Vector(); 123 124 // ----------------------------------------------------------- Constructors 125 126 /*** 127 * No-arg constructor. 128 * 129 * @since 1.0 130 */ 131 public PostMethod() { 132 super(); 133 } 134 135 /*** 136 * Constructor specifying a URI. 137 * 138 * @param uri either an absolute or relative URI 139 * 140 * @since 1.0 141 */ 142 public PostMethod(String uri) { 143 super(uri); 144 } 145 146 /*** 147 * Constructor specifying a URI and a tempDir. 148 * 149 * @param uri either an absolute or relative URI 150 * @param tempDir directory to store temp files in 151 * 152 * @deprecated the client is responsible for disk I/O 153 * @since 1.0 154 */ 155 public PostMethod(String uri, String tempDir) { 156 super(uri, tempDir); 157 } 158 159 /*** 160 * Constructor specifying a URI, tempDir and tempFile. 161 * 162 * @param uri either an absolute or relative URI 163 * @param tempDir directory to store temp files in 164 * @param tempFile file to store temporary data in 165 * 166 * @deprecated the client is responsible for disk I/O 167 * @since 1.0 168 */ 169 public PostMethod(String uri, String tempDir, String tempFile) { 170 super(uri, tempDir, tempFile); 171 } 172 173 // ----------------------------------------------------- Instance Methods 174 175 /*** 176 * Returns <tt>"POST"</tt>. 177 * 178 * @return <tt>"POST"</tt> 179 * 180 * @since 2.0 181 */ 182 public String getName() { 183 return "POST"; 184 } 185 186 187 /*** 188 * Returns <tt>true</tt> if there is a request body to be sent. 189 * 190 * <P>This method must be overwritten by sub-classes that implement 191 * alternative request content input methods 192 * </p> 193 * 194 * @return boolean 195 * 196 * @since 2.0beta1 197 */ 198 protected boolean hasRequestContent() { 199 LOG.trace("enter PostMethod.hasRequestContent()"); 200 if (!this.params.isEmpty()) { 201 return true; 202 } else { 203 return super.hasRequestContent(); 204 } 205 } 206 207 /*** 208 * Clears request body. 209 * 210 * <p>This method must be overwritten by sub-classes that implement 211 * alternative request content input methods</p> 212 * 213 * @since 2.0beta1 214 */ 215 protected void clearRequestBody() { 216 LOG.trace("enter PostMethod.clearRequestBody()"); 217 this.params.clear(); 218 super.clearRequestBody(); 219 } 220 221 /*** 222 * Generates the request body. 223 * 224 * <p>This method must be overwritten by sub-classes that implement 225 * alternative request content input methods 226 * </p> 227 * 228 * @return request body as an array of bytes. If the request content 229 * has not been set, returns <tt>null</null>. 230 * 231 * @since 2.0beta1 232 */ 233 protected byte[] generateRequestBody() { 234 LOG.trace("enter PostMethod.renerateRequestBody()"); 235 if (!this.params.isEmpty()) { 236 String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet()); 237 return HttpConstants.getContentBytes(content); 238 } else { 239 return super.generateRequestBody(); 240 } 241 } 242 243 244 /*** 245 * Sets the value of parameter with parameterName to parameterValue. This method 246 * does not preserve the initial insertion order. 247 * 248 * @param parameterName name of the parameter 249 * @param parameterValue value of the parameter 250 * 251 * @since 2.0 252 */ 253 public void setParameter(String parameterName, String parameterValue) { 254 LOG.trace("enter PostMethod.setParameter(String, String)"); 255 256 removeParameter(parameterName); 257 addParameter(parameterName, parameterValue); 258 } 259 260 /*** 261 * Gets the parameter of the specified name. If there exists more than one 262 * parameter with the name paramName, then only the first one is returned. 263 * 264 * @param paramName name of the parameter 265 * 266 * @return If a parameter exists with the name argument, the coresponding 267 * NameValuePair is returned. Otherwise null. 268 * 269 * @since 2.0 270 * 271 */ 272 public NameValuePair getParameter(String paramName) { 273 LOG.trace("enter PostMethod.getParameter(String)"); 274 275 if (paramName == null) { 276 return null; 277 } 278 279 Iterator iter = this.params.iterator(); 280 281 while (iter.hasNext()) { 282 NameValuePair parameter = (NameValuePair) iter.next(); 283 284 if (paramName.equals(parameter.getName())) { 285 return parameter; 286 } 287 } 288 return null; 289 } 290 291 /*** 292 * Gets the parameters currently added to the PostMethod. If there are no 293 * parameters, a valid array is returned with zero elements. The returned 294 * array object contains an array of pointers to the internal data 295 * members. 296 * 297 * @return An array of the current parameters 298 * 299 * @since 2.0 300 * 301 */ 302 public NameValuePair[] getParameters() { 303 LOG.trace("enter PostMethod.getParameters()"); 304 305 int numPairs = this.params.size(); 306 Object[] objectArr = this.params.toArray(); 307 NameValuePair[] nvPairArr = new NameValuePair[numPairs]; 308 309 for (int i = 0; i < numPairs; i++) { 310 nvPairArr[i] = (NameValuePair) objectArr[i]; 311 } 312 313 return nvPairArr; 314 } 315 316 /*** 317 * Adds a new parameter to be used in the POST request body. 318 * 319 * @param paramName The parameter name to add. 320 * @param paramValue The parameter value to add. 321 * 322 * @throws IllegalArgumentException if either argument is null 323 * 324 * @since 1.0 325 */ 326 public void addParameter(String paramName, String paramValue) 327 throws IllegalArgumentException { 328 LOG.trace("enter PostMethod.addParameter(String, String)"); 329 330 if ((paramName == null) || (paramValue == null)) { 331 throw new IllegalArgumentException( 332 "Arguments to addParameter(String, String) cannot be null"); 333 } 334 super.clearRequestBody(); 335 this.params.add(new NameValuePair(paramName, paramValue)); 336 } 337 338 /*** 339 * Adds a new parameter to be used in the POST request body. 340 * 341 * @param param The parameter to add. 342 * 343 * @throws IllegalArgumentException if the argument is null or contains 344 * null values 345 * 346 * @since 2.0 347 */ 348 public void addParameter(NameValuePair param) 349 throws IllegalArgumentException { 350 LOG.trace("enter PostMethod.addParameter(NameValuePair)"); 351 352 if (param == null) { 353 throw new IllegalArgumentException("NameValuePair may not be null"); 354 } 355 addParameter(param.getName(), param.getValue()); 356 } 357 358 /*** 359 * Adds an array of parameters to be used in the POST request body. Logs a 360 * warning if the parameters argument is null. 361 * 362 * @param parameters The array of parameters to add. 363 * 364 * @since 2.0 365 */ 366 public void addParameters(NameValuePair[] parameters) { 367 LOG.trace("enter PostMethod.addParameters(NameValuePair[])"); 368 369 if (parameters == null) { 370 LOG.warn("Attempt to addParameters(null) ignored"); 371 } else { 372 super.clearRequestBody(); 373 for (int i = 0; i < parameters.length; i++) { 374 this.params.add(parameters[i]); 375 } 376 } 377 } 378 379 /*** 380 * Removes all parameters with the given paramName. If there is more than 381 * one parameter with the given paramName, all of them are removed. If 382 * there is just one, it is removed. If there are none, then the request 383 * is ignored. 384 * 385 * @param paramName The parameter name to remove. 386 * 387 * @return true if at least one parameter was removed 388 * 389 * @throws IllegalArgumentException When the parameter name passed is null 390 * 391 * @since 2.0 392 */ 393 public boolean removeParameter(String paramName) 394 throws IllegalArgumentException { 395 LOG.trace("enter PostMethod.removeParameter(String)"); 396 397 if (paramName == null) { 398 throw new IllegalArgumentException( 399 "Argument passed to removeParameter(String) cannot be null"); 400 } 401 boolean removed = false; 402 Iterator iter = this.params.iterator(); 403 404 while (iter.hasNext()) { 405 NameValuePair pair = (NameValuePair) iter.next(); 406 407 if (paramName.equals(pair.getName())) { 408 iter.remove(); 409 removed = true; 410 } 411 } 412 return removed; 413 } 414 415 /*** 416 * Removes all parameter with the given paramName and paramValue. If there 417 * is more than one parameter with the given paramName, only one is 418 * removed. If there are none, then the request is ignored. 419 * 420 * @param paramName The parameter name to remove. 421 * @param paramValue The parameter value to remove. 422 * 423 * @return true if a parameter was removed. 424 * 425 * @throws IllegalArgumentException when param name or value are null 426 * 427 * @since 2.0 428 */ 429 public boolean removeParameter(String paramName, String paramValue) 430 throws IllegalArgumentException { 431 LOG.trace("enter PostMethod.removeParameter(String, String)"); 432 433 if (paramName == null) { 434 throw new IllegalArgumentException("Parameter name may not be null"); 435 } 436 if (paramValue == null) { 437 throw new IllegalArgumentException("Parameter value may not be null"); 438 } 439 440 Iterator iter = this.params.iterator(); 441 442 while (iter.hasNext()) { 443 NameValuePair pair = (NameValuePair) iter.next(); 444 445 if (paramName.equals(pair.getName()) 446 && paramValue.equals(pair.getValue())) { 447 iter.remove(); 448 return true; 449 } 450 } 451 452 return false; 453 } 454 455 /*** 456 * Sets an array of parameters to be used in the POST request body 457 * 458 * @param parametersBody The array of parameters to add. 459 * 460 * @throws IllegalArgumentException when param parameters are null 461 * 462 * @since 2.0beta1 463 */ 464 public void setRequestBody(NameValuePair[] parametersBody) 465 throws IllegalArgumentException { 466 LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])"); 467 468 if (parametersBody == null) { 469 throw new IllegalArgumentException("Array of parameters may not be null"); 470 } 471 clearRequestBody(); 472 addParameters(parametersBody); 473 } 474 475 /*** 476 * Adds <tt>Content Type: application/x-www-form-urlencoded</tt> header in 477 * addition to the "standard" set of headers, if no <tt>Content Type</tt> 478 * header has been set by the user 479 * 480 * @param state the {@link HttpState state} information associated with this method 481 * @param conn the {@link HttpConnection connection} used to execute 482 * this HTTP method 483 * 484 * @throws IOException if an I/O (transport) error occurs 485 * @throws HttpException if a protocol exception occurs. 486 * @throws HttpRecoverableException if a recoverable transport error occurs. 487 * Usually this kind of exceptions can be recovered from by 488 * retrying the HTTP method 489 * 490 * @since 2.0 491 */ 492 protected void addRequestHeaders(HttpState state, HttpConnection conn) 493 throws IOException, HttpException { 494 super.addRequestHeaders(state, conn); 495 496 if (!this.params.isEmpty()) { 497 //there are some parameters, so set the contentType header 498 if (getRequestHeader("Content-Type") == null) { 499 setRequestHeader("Content-Type", FORM_URL_ENCODED_CONTENT_TYPE); 500 } 501 } 502 } 503 504 }

This page was automatically generated by Maven