View Javadoc

    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java,v 1.58 2004/08/08 12:50:09 olegk Exp $
    3    * $Revision: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    5    *
    6    * ====================================================================
    7    *
    8    *  Licensed to the Apache Software Foundation (ASF) under one or more
    9    *  contributor license agreements.  See the NOTICE file distributed with
    10   *  this work for additional information regarding copyright ownership.
    11   *  The ASF licenses this file to You under the Apache License, Version 2.0
    12   *  (the "License"); you may not use this file except in compliance with
    13   *  the License.  You may obtain a copy of the License at
    14   *
    15   *      http://www.apache.org/licenses/LICENSE-2.0
    16   *
    17   *  Unless required by applicable law or agreed to in writing, software
    18   *  distributed under the License is distributed on an "AS IS" BASIS,
    19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    20   *  See the License for the specific language governing permissions and
    21   *  limitations under the License.
    22   * ====================================================================
    23   *
    24   * This software consists of voluntary contributions made by many
    25   * individuals on behalf of the Apache Software Foundation.  For more
    26   * information on the Apache Software Foundation, please see
    27   * <http://www.apache.org/>.
    28   *
    29   */
    30
    31  package org.apache.commons.httpclient.methods;
    32
    33  import java.util.Iterator;
    34  import java.util.Vector;
    35
    36  import org.apache.commons.httpclient.NameValuePair;
    37  import org.apache.commons.httpclient.util.EncodingUtil;
    38  import org.apache.commons.logging.Log;
    39  import org.apache.commons.logging.LogFactory;
    40
    41  /**
    42   * Implements the HTTP POST method.
    43   * <p>
    44   * The HTTP POST method is defined in section 9.5 of
    45   * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
    46   * <blockquote>
    47   * The POST method is used to request that the origin server accept the entity
    48   * enclosed in the request as a new subordinate of the resource identified by
    49   * the Request-URI in the Request-Line. POST is designed to allow a uniform
    50   * method to cover the following functions:
    51   * <ul>
    52   *   <li>Annotation of existing resources</li>
    53   *   <li>Posting a message to a bulletin board, newsgroup, mailing list, or
    54   *     similar group of articles</li>
    55   *   <li>Providing a block of data, such as the result of submitting a form,
    56   *     to a data-handling process</li>
    57   *   <li>Extending a database through an append operation</li>
    58   * </ul>
    59   * </blockquote>
    60   * </p>
    61   *
    62   * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
    63   * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
    64   * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
    65   * @author Ortwin Gl???ck
    66   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
    67   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    68   *
    69   * @version $Revision: 480424 $
    70   * @since 1.0
    71   */
    72  public class PostMethod extends EntityEnclosingMethod {
    73      // -------------------------------------------------------------- Constants
    74
    75      /** Log object for this class. */
    76      private static final Log LOG = LogFactory.getLog(PostMethod.class);
    77
    78      /** The Content-Type for www-form-urlencoded. */
    79      public static final String FORM_URL_ENCODED_CONTENT_TYPE =
    80          "application/x-www-form-urlencoded";
    81
    82      /**
    83       * The buffered request body consisting of <code>NameValuePair</code>s.
    84       */
    85      private Vector params = new Vector();
    86
    87      // ----------------------------------------------------------- Constructors
    88
    89      /**
    90       * No-arg constructor.
    91       *
    92       * @since 1.0
    93       */
    94      public PostMethod() {
    95          super();
    96      }
    97
    98      /**
    99       * Constructor specifying a URI.
    100      *
    101      * @param uri either an absolute or relative URI
    102      *
    103      * @since 1.0
    104      */
    105     public PostMethod(String uri) {
    106         super(uri);
    107     }
    108
    109     // ----------------------------------------------------- Instance Methods
    110
    111     /**
    112      * Returns <tt>"POST"</tt>.
    113      *
    114      * @return <tt>"POST"</tt>
    115      *
    116      * @since 2.0
    117      */
    118     public String getName() {
    119         return "POST";
    120     }
    121
    122
    123     /**
    124      * Returns <tt>true</tt> if there is a request body to be sent.
    125      *
    126      * <P>This method must be overwritten by sub-classes that implement
    127      * alternative request content input methods
    128      * </p>
    129      *
    130      * @return boolean
    131      *
    132      * @since 2.0beta1
    133      */
    134     protected boolean hasRequestContent() {
    135         LOG.trace("enter PostMethod.hasRequestContent()");
    136         if (!this.params.isEmpty()) {
    137             return true;
    138         } else {
    139             return super.hasRequestContent();
    140         }
    141     }
    142
    143     /**
    144      * Clears request body.
    145      *
    146      * <p>This method must be overwritten by sub-classes that implement
    147      * alternative request content input methods</p>
    148      *
    149      * @since 2.0beta1
    150      */
    151     protected void clearRequestBody() {
    152         LOG.trace("enter PostMethod.clearRequestBody()");
    153         this.params.clear();
    154         super.clearRequestBody();
    155     }
    156
    157     /**
    158      * Generates a request entity from the post parameters, if present.  Calls
    159      * {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set.
    160      *
    161      * @since 3.0
    162      */
    163     protected RequestEntity generateRequestEntity() {
    164         if (!this.params.isEmpty()) {
    165             // Use a ByteArrayRequestEntity instead of a StringRequestEntity.
    166             // This is to avoid potential encoding issues.  Form url encoded strings
    167             // are ASCII by definition but the content type may not be.  Treating the content
    168             // as bytes allows us to keep the current charset without worrying about how
    169             // this charset will effect the encoding of the form url encoded string.
    170             String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet());
    171             ByteArrayRequestEntity entity = new ByteArrayRequestEntity(
    172                 EncodingUtil.getAsciiBytes(content),
    173                 FORM_URL_ENCODED_CONTENT_TYPE
    174             );
    175             return entity;
    176         } else {
    177             return super.generateRequestEntity();
    178         }
    179     }
    180
    181     /**
    182      * Sets the value of parameter with parameterName to parameterValue. This method
    183      * does not preserve the initial insertion order.
    184      *
    185      * @param parameterName name of the parameter
    186      * @param parameterValue value of the parameter
    187      *
    188      * @since 2.0
    189      */
    190     public void setParameter(String parameterName, String parameterValue) {
    191         LOG.trace("enter PostMethod.setParameter(String, String)");
    192
    193         removeParameter(parameterName);
    194         addParameter(parameterName, parameterValue);
    195     }
    196
    197     /**
    198      * Gets the parameter of the specified name. If there exists more than one
    199      * parameter with the name paramName, then only the first one is returned.
    200      *
    201      * @param paramName name of the parameter
    202      *
    203      * @return If a parameter exists with the name argument, the coresponding
    204      *         NameValuePair is returned.  Otherwise null.
    205      *
    206      * @since 2.0
    207      *
    208      */
    209     public NameValuePair getParameter(String paramName) {
    210         LOG.trace("enter PostMethod.getParameter(String)");
    211
    212         if (paramName == null) {
    213             return null;
    214         }
    215
    216         Iterator iter = this.params.iterator();
    217
    218         while (iter.hasNext()) {
    219             NameValuePair parameter = (NameValuePair) iter.next();
    220
    221             if (paramName.equals(parameter.getName())) {
    222                 return parameter;
    223             }
    224         }
    225         return null;
    226     }
    227
    228     /**
    229      * Gets the parameters currently added to the PostMethod. If there are no
    230      * parameters, a valid array is returned with zero elements. The returned
    231      * array object contains an array of pointers to  the internal data
    232      * members.
    233      *
    234      * @return An array of the current parameters
    235      *
    236      * @since 2.0
    237      *
    238      */
    239     public NameValuePair[] getParameters() {
    240         LOG.trace("enter PostMethod.getParameters()");
    241
    242         int numPairs = this.params.size();
    243         Object[] objectArr = this.params.toArray();
    244         NameValuePair[] nvPairArr = new NameValuePair[numPairs];
    245
    246         for (int i = 0; i < numPairs; i++) {
    247             nvPairArr[i] = (NameValuePair) objectArr[i];
    248         }
    249
    250         return nvPairArr;
    251     }
    252
    253     /**
    254      * Adds a new parameter to be used in the POST request body.
    255      *
    256      * @param paramName The parameter name to add.
    257      * @param paramValue The parameter value to add.
    258      *
    259      * @throws IllegalArgumentException if either argument is null
    260      *
    261      * @since 1.0
    262      */
    263     public void addParameter(String paramName, String paramValue)
    264     throws IllegalArgumentException {
    265         LOG.trace("enter PostMethod.addParameter(String, String)");
    266
    267         if ((paramName == null) || (paramValue == null)) {
    268             throw new IllegalArgumentException(
    269                 "Arguments to addParameter(String, String) cannot be null");
    270         }
    271         super.clearRequestBody();
    272         this.params.add(new NameValuePair(paramName, paramValue));
    273     }
    274
    275     /**
    276      * Adds a new parameter to be used in the POST request body.
    277      *
    278      * @param param The parameter to add.
    279      *
    280      * @throws IllegalArgumentException if the argument is null or contains
    281      *         null values
    282      *
    283      * @since 2.0
    284      */
    285     public void addParameter(NameValuePair param)
    286     throws IllegalArgumentException {
    287         LOG.trace("enter PostMethod.addParameter(NameValuePair)");
    288
    289         if (param == null) {
    290             throw new IllegalArgumentException("NameValuePair may not be null");
    291         }
    292         addParameter(param.getName(), param.getValue());
    293     }
    294
    295     /**
    296      * Adds an array of parameters to be used in the POST request body. Logs a
    297      * warning if the parameters argument is null.
    298      *
    299      * @param parameters The array of parameters to add.
    300      *
    301      * @since 2.0
    302      */
    303     public void addParameters(NameValuePair[] parameters) {
    304         LOG.trace("enter PostMethod.addParameters(NameValuePair[])");
    305
    306         if (parameters == null) {
    307             LOG.warn("Attempt to addParameters(null) ignored");
    308         } else {
    309             super.clearRequestBody();
    310             for (int i = 0; i < parameters.length; i++) {
    311                 this.params.add(parameters[i]);
    312             }
    313         }
    314     }
    315
    316     /**
    317      * Removes all parameters with the given paramName. If there is more than
    318      * one parameter with the given paramName, all of them are removed.  If
    319      * there is just one, it is removed.  If there are none, then the request
    320      * is ignored.
    321      *
    322      * @param paramName The parameter name to remove.
    323      *
    324      * @return true if at least one parameter was removed
    325      *
    326      * @throws IllegalArgumentException When the parameter name passed is null
    327      *
    328      * @since 2.0
    329      */
    330     public boolean removeParameter(String paramName)
    331     throws IllegalArgumentException {
    332         LOG.trace("enter PostMethod.removeParameter(String)");
    333
    334         if (paramName == null) {
    335             throw new IllegalArgumentException(
    336                 "Argument passed to removeParameter(String) cannot be null");
    337         }
    338         boolean removed = false;
    339         Iterator iter = this.params.iterator();
    340
    341         while (iter.hasNext()) {
    342             NameValuePair pair = (NameValuePair) iter.next();
    343
    344             if (paramName.equals(pair.getName())) {
    345                 iter.remove();
    346                 removed = true;
    347             }
    348         }
    349         return removed;
    350     }
    351
    352     /**
    353      * Removes all parameter with the given paramName and paramValue. If there
    354      * is more than one parameter with the given paramName, only one is
    355      * removed.  If there are none, then the request is ignored.
    356      *
    357      * @param paramName The parameter name to remove.
    358      * @param paramValue The parameter value to remove.
    359      *
    360      * @return true if a parameter was removed.
    361      *
    362      * @throws IllegalArgumentException when param name or value are null
    363      *
    364      * @since 2.0
    365      */
    366     public boolean removeParameter(String paramName, String paramValue)
    367     throws IllegalArgumentException {
    368         LOG.trace("enter PostMethod.removeParameter(String, String)");
    369
    370         if (paramName == null) {
    371             throw new IllegalArgumentException("Parameter name may not be null");
    372         }
    373         if (paramValue == null) {
    374             throw new IllegalArgumentException("Parameter value may not be null");
    375         }
    376
    377         Iterator iter = this.params.iterator();
    378
    379         while (iter.hasNext()) {
    380             NameValuePair pair = (NameValuePair) iter.next();
    381
    382             if (paramName.equals(pair.getName())
    383                 && paramValue.equals(pair.getValue())) {
    384                 iter.remove();
    385                 return true;
    386             }
    387         }
    388
    389         return false;
    390     }
    391
    392     /**
    393      * Sets an array of parameters to be used in the POST request body
    394      *
    395      * @param parametersBody The array of parameters to add.
    396      *
    397      * @throws IllegalArgumentException when param parameters are null
    398      *
    399      * @since 2.0beta1
    400      */
    401     public void setRequestBody(NameValuePair[] parametersBody)
    402     throws IllegalArgumentException {
    403         LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])");
    404
    405         if (parametersBody == null) {
    406             throw new IllegalArgumentException("Array of parameters may not be null");
    407         }
    408         clearRequestBody();
    409         addParameters(parametersBody);
    410     }
    411 }