View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java,v 1.42 2003/04/19 22:29:32 mbecke Exp $ 3 * $Revision: 1.42 $ 4 * $Date: 2003/04/19 22:29:32 $ 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.URIException; 75 import org.apache.commons.httpclient.util.URIUtil; 76 import org.apache.commons.logging.Log; 77 import org.apache.commons.logging.LogFactory; 78 79 /*** 80 * Implements the HTTP POST specification. 81 * <p> 82 * The HTTP POST method is defined in section 8.3 of 83 * <a href="http://www.ietf.org/rfc/rfc1945.txt">RFC1945</a>: 84 * <blockquote> 85 * The POST method is used to request that the origin server accept the entity 86 * enclosed in the request as a new subordinate of the resource identified by 87 * the Request-URI in the Request-Line. POST is designed to allow a uniform 88 * method to cover the following functions: 89 * <ul> 90 * <li>Annotation of existing resources</li> 91 * <li>Posting a message to a bulletin board, newsgroup, mailing list, or 92 * similar group of articles</li> 93 * <li>Providing a block of data, such as the result of submitting a form, 94 * to a data-handling process</li> 95 * <li>Extending a database through an append operation</li> 96 * </ul> 97 * </blockquote> 98 * </p> 99 * 100 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a> 101 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a> 102 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> 103 * @author Ortwin Gl�ck 104 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 105 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 106 * 107 * @version $Revision: 1.42 $ 108 * @since 1.0 109 */ 110 public class PostMethod extends EntityEnclosingMethod { 111 // -------------------------------------------------------------- Constants 112 113 /*** Log object for this class. */ 114 private static final Log LOG = LogFactory.getLog(PostMethod.class); 115 116 /*** The Content-Type for www-form-urlcoded. */ 117 public static final String FORM_URL_ENCODED_CONTENT_TYPE = 118 "application/x-www-form-urlencoded"; 119 120 /*** 121 * The buffered request body consisting of <code>NameValuePair</code>s. 122 */ 123 private Vector params = new Vector(); 124 125 // ----------------------------------------------------------- Constructors 126 127 /*** 128 * No-arg constructor. 129 * 130 * @since 1.0 131 */ 132 public PostMethod() { 133 super(); 134 } 135 136 /*** 137 * Constructor specifying a URI. 138 * 139 * @param uri either an absolute or relative URI 140 * 141 * @since 1.0 142 */ 143 public PostMethod(String uri) { 144 super(uri); 145 } 146 147 /*** 148 * Constructor specifying a URI and a tempDir. 149 * 150 * @param uri either an absolute or relative URI 151 * @param tempDir directory to store temp files in 152 * 153 * @deprecated the client is responsible for disk I/O 154 * @since 1.0 155 */ 156 public PostMethod(String uri, String tempDir) { 157 super(uri, tempDir); 158 } 159 160 /*** 161 * Constructor specifying a URI, tempDir and tempFile. 162 * 163 * @param uri either an absolute or relative URI 164 * @param tempDir directory to store temp files in 165 * @param tempFile file to store temporary data in 166 * 167 * @deprecated the client is responsible for disk I/O 168 * @since 1.0 169 */ 170 public PostMethod(String uri, String tempDir, String tempFile) { 171 super(uri, tempDir, tempFile); 172 } 173 174 // ----------------------------------------------------- Instance Methods 175 176 /*** 177 * Returns <tt>"POST"</tt>. 178 * 179 * @return <tt>"POST"</tt> 180 * 181 * @since 2.0 182 */ 183 public String getName() { 184 return "POST"; 185 } 186 187 188 /*** 189 * Returns <tt>true</tt> if there is a request body to be sent. 190 * 191 * <P>This method must be overwritten by sub-classes that implement 192 * alternative request content input methods 193 * </p> 194 * 195 * @return boolean 196 * 197 * @since 2.0beta1 198 */ 199 protected boolean hasRequestContent() { 200 LOG.trace("enter PostMethod.hasRequestContent()"); 201 if (!this.params.isEmpty()) { 202 return true; 203 } else { 204 return super.hasRequestContent(); 205 } 206 } 207 208 /*** 209 * Clears request body. 210 * 211 * <p>This method must be overwritten by sub-classes that implement 212 * alternative request content input methods</p> 213 * 214 * @since 2.0beta1 215 */ 216 protected void clearRequestBody() { 217 LOG.trace("enter PostMethod.clearRequestBody()"); 218 this.params.clear(); 219 super.clearRequestBody(); 220 } 221 222 223 /*** 224 * Generates request body. 225 * 226 * <p>This method must be overwritten by sub-classes that implement 227 * alternative request content input methods 228 * </p> 229 * 230 * @return request body as an array of bytes. If the request content 231 * has not been set, returns <tt>null</null>. 232 * 233 * @since 2.0beta1 234 */ 235 protected byte[] generateRequestBody() { 236 LOG.trace("enter PostMethod.renerateRequestBody()"); 237 if (!this.params.isEmpty()) { 238 String charset = getRequestCharSet(); 239 StringBuffer buff = new StringBuffer(); 240 241 for (int i = 0; i < this.params.size(); i++) { 242 if (i > 0) { 243 buff.append("&"); 244 } 245 NameValuePair parameter = (NameValuePair) this.params.get(i); 246 String queryName = null; 247 try { 248 queryName = URIUtil.encodeWithinQuery(parameter.getName(), charset); 249 } catch (URIException e) { 250 if (LOG.isWarnEnabled()) { 251 LOG.warn("Encosing error: " + e.toString()); 252 } 253 queryName = parameter.getName(); 254 } 255 256 buff.append(queryName).append("="); 257 String queryValue = null; 258 259 try { 260 queryValue = URIUtil.encodeWithinQuery(parameter.getValue(), charset); 261 } catch (URIException e) { 262 if (LOG.isWarnEnabled()) { 263 LOG.warn("Encosing error: " + e.toString()); 264 } 265 queryValue = parameter.getValue(); 266 } 267 buff.append(queryValue); 268 } 269 return HttpConstants.getContentBytes(buff.toString()); 270 } else { 271 return super.generateRequestBody(); 272 } 273 } 274 275 276 /*** 277 * Set the value of parameter with parameterName to parameterValue. Does 278 * not preserve the initial insertion order. 279 * 280 * @param parameterName name of the parameter 281 * @param parameterValue value of the parameter 282 * 283 * @since 2.0 284 */ 285 public void setParameter(String parameterName, String parameterValue) { 286 LOG.trace("enter PostMethod.setParameter(String, String)"); 287 288 removeParameter(parameterName, parameterValue); 289 addParameter(parameterName, parameterValue); 290 } 291 292 /*** 293 * Gets the parameter of the specified name. If there exists more than one 294 * parameter with the name paramName, then only the first one is returned. 295 * 296 * @param paramName name of the parameter 297 * 298 * @return If a parameter exists with the name argument, the coresponding 299 * NameValuePair is returned. Otherwise null. 300 * 301 * @since 2.0 302 * 303 */ 304 public NameValuePair getParameter(String paramName) { 305 LOG.trace("enter PostMethod.getParameter(String)"); 306 307 if (paramName == null) { 308 return null; 309 } 310 311 Iterator iter = this.params.iterator(); 312 313 while (iter.hasNext()) { 314 NameValuePair parameter = (NameValuePair) iter.next(); 315 316 if (paramName.equals(parameter.getName())) { 317 return parameter; 318 } 319 } 320 return null; 321 } 322 323 /*** 324 * Gets the parameters currently added to the PostMethod. If there are no 325 * parameters, a valid array is returned with zero elements. The returned 326 * array object contains an array of pointers to the internal data 327 * members. 328 * 329 * @return An array of the current parameters 330 * 331 * @since 2.0 332 * 333 */ 334 public NameValuePair[] getParameters() { 335 LOG.trace("enter PostMethod.getParameters()"); 336 337 int numPairs = this.params.size(); 338 Object[] objectArr = this.params.toArray(); 339 NameValuePair[] nvPairArr = new NameValuePair[numPairs]; 340 341 for (int i = 0; i < numPairs; i++) { 342 nvPairArr[i] = (NameValuePair) objectArr[i]; 343 } 344 345 return nvPairArr; 346 } 347 348 /*** 349 * Add a new parameter to be used in the POST request body. 350 * 351 * @param paramName The parameter name to add. 352 * @param paramValue The parameter value to add. 353 * 354 * @throws IllegalArgumentException if either argument is null 355 * 356 * @since 1.0 357 */ 358 public void addParameter(String paramName, String paramValue) 359 throws IllegalArgumentException { 360 LOG.trace("enter PostMethod.addParameter(String, String)"); 361 362 if ((paramName == null) || (paramValue == null)) { 363 throw new IllegalArgumentException( 364 "Arguments to addParameter(String, String) cannot be null"); 365 } 366 super.clearRequestBody(); 367 this.params.add(new NameValuePair(paramName, paramValue)); 368 } 369 370 /*** 371 * Add a new parameter to be used in the POST request body. 372 * 373 * @param param The parameter to add. 374 * 375 * @throws IllegalArgumentException if the argument is null or contains 376 * null values 377 * 378 * @since 2.0 379 */ 380 public void addParameter(NameValuePair param) 381 throws IllegalArgumentException { 382 LOG.trace("enter PostMethod.addParameter(NameValuePair)"); 383 384 if (param == null) { 385 throw new IllegalArgumentException("NameValuePair may not be null"); 386 } 387 addParameter(param.getName(), param.getValue()); 388 } 389 390 /*** 391 * Add an Array of parameters to be used in the POST request body. Logs a 392 * warning if the parameters argument is null. 393 * 394 * @param parameters The array of parameters to add. 395 * 396 * @since 2.0 397 */ 398 public void addParameters(NameValuePair[] parameters) { 399 LOG.trace("enter PostMethod.addParameters(NameValuePair[])"); 400 401 if (parameters == null) { 402 LOG.warn("Attempt to addParameters(null) ignored"); 403 } else { 404 for (int i = 0; i < parameters.length; i++) { 405 addParameter(parameters[i]); 406 } 407 } 408 } 409 410 /*** 411 * Removes all parameters with the given paramName. If there is more than 412 * one parameter with the given paramName, all of them are removed. If 413 * there is just one, it is removed. If there are none, then the request 414 * is ignored. 415 * 416 * @param paramName The parameter name to remove. 417 * 418 * @return true if at least one parameter was removed 419 * 420 * @throws IllegalArgumentException When the parameter name passed is null 421 * 422 * @since 2.0 423 */ 424 public boolean removeParameter(String paramName) 425 throws IllegalArgumentException { 426 LOG.trace("enter PostMethod.removeParameter(String)"); 427 428 if (paramName == null) { 429 throw new IllegalArgumentException( 430 "Argument passed to removeParameter(String) cannot be null"); 431 } 432 boolean removed = true; 433 Iterator iter = this.params.iterator(); 434 435 while (iter.hasNext()) { 436 NameValuePair pair = (NameValuePair) iter.next(); 437 438 if (paramName.equals(pair.getName())) { 439 iter.remove(); 440 removed = true; 441 } 442 } 443 return removed; 444 } 445 446 /*** 447 * Removes all parameter with the given paramName and paramValue. If there 448 * is more than one parameter with the given paramName, only one is 449 * removed. If there are none, then the request is ignored. 450 * 451 * @param paramName The parameter name to remove. 452 * @param paramValue The parameter value to remove. 453 * 454 * @return true if a parameter was removed. 455 * 456 * @throws IllegalArgumentException when param name or value are null 457 * 458 * @since 2.0 459 */ 460 public boolean removeParameter(String paramName, String paramValue) 461 throws IllegalArgumentException { 462 LOG.trace("enter PostMethod.removeParameter(String, String)"); 463 464 if (paramName == null) { 465 throw new IllegalArgumentException("Parameter name may not be null"); 466 } 467 if (paramValue == null) { 468 throw new IllegalArgumentException("Parameter value may not be null"); 469 } 470 471 Iterator iter = this.params.iterator(); 472 473 while (iter.hasNext()) { 474 NameValuePair pair = (NameValuePair) iter.next(); 475 476 if (paramName.equals(pair.getName()) 477 && paramValue.equals(pair.getValue())) { 478 iter.remove(); 479 return true; 480 } 481 } 482 483 return false; 484 } 485 486 /*** 487 * Set an Array of parameters to be used in the POST request body 488 * 489 * @param parametersBody The array of parameters to add. 490 * 491 * @throws IllegalArgumentException when param parameters are null 492 * 493 * @since 2.0beta1 494 */ 495 public void setRequestBody(NameValuePair[] parametersBody) 496 throws IllegalArgumentException { 497 LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])"); 498 499 if (parametersBody == null) { 500 throw new IllegalArgumentException("Array of parameters may not be null"); 501 } 502 clearRequestBody(); 503 addParameters(parametersBody); 504 } 505 506 /*** 507 * Override method of {@link org.apache.commons.httpclient.HttpMethodBase} 508 * to also add <tt>Content-Type</tt> header when appropriate. 509 * 510 * @param state the client state 511 * @param conn the {@link HttpConnection} the headers will eventually be 512 * written to 513 * @throws IOException when an error occurs writing the request 514 * @throws HttpException when a HTTP protocol error occurs 515 * 516 * @since 2.0 517 */ 518 protected void addRequestHeaders(HttpState state, HttpConnection conn) 519 throws IOException, HttpException { 520 super.addRequestHeaders(state, conn); 521 522 if (!this.params.isEmpty()) { 523 //there are some parameters, so set the contentType header 524 if (getRequestHeader("Content-Type") == null) { 525 setRequestHeader("Content-Type", FORM_URL_ENCODED_CONTENT_TYPE); 526 } 527 } 528 } 529 530 }

This page was automatically generated by Maven