001: /*
002: * $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 $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.methods;
032:
033: import java.util.Iterator;
034: import java.util.Vector;
035:
036: import org.apache.commons.httpclient.NameValuePair;
037: import org.apache.commons.httpclient.util.EncodingUtil;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: /**
042: * Implements the HTTP POST method.
043: * <p>
044: * The HTTP POST method is defined in section 9.5 of
045: * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
046: * <blockquote>
047: * The POST method is used to request that the origin server accept the entity
048: * enclosed in the request as a new subordinate of the resource identified by
049: * the Request-URI in the Request-Line. POST is designed to allow a uniform
050: * method to cover the following functions:
051: * <ul>
052: * <li>Annotation of existing resources</li>
053: * <li>Posting a message to a bulletin board, newsgroup, mailing list, or
054: * similar group of articles</li>
055: * <li>Providing a block of data, such as the result of submitting a form,
056: * to a data-handling process</li>
057: * <li>Extending a database through an append operation</li>
058: * </ul>
059: * </blockquote>
060: * </p>
061: *
062: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
063: * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
064: * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
065: * @author Ortwin Gl???ck
066: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
067: * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
068: *
069: * @version $Revision: 480424 $
070: * @since 1.0
071: */
072: public class PostMethod extends EntityEnclosingMethod {
073: // -------------------------------------------------------------- Constants
074:
075: /** Log object for this class. */
076: private static final Log LOG = LogFactory.getLog(PostMethod.class);
077:
078: /** The Content-Type for www-form-urlencoded. */
079: public static final String FORM_URL_ENCODED_CONTENT_TYPE = "application/x-www-form-urlencoded";
080:
081: /**
082: * The buffered request body consisting of <code>NameValuePair</code>s.
083: */
084: private Vector params = new Vector();
085:
086: // ----------------------------------------------------------- Constructors
087:
088: /**
089: * No-arg constructor.
090: *
091: * @since 1.0
092: */
093: public PostMethod() {
094: super ();
095: }
096:
097: /**
098: * Constructor specifying a URI.
099: *
100: * @param uri either an absolute or relative URI
101: *
102: * @since 1.0
103: */
104: public PostMethod(String uri) {
105: super (uri);
106: }
107:
108: // ----------------------------------------------------- Instance Methods
109:
110: /**
111: * Returns <tt>"POST"</tt>.
112: *
113: * @return <tt>"POST"</tt>
114: *
115: * @since 2.0
116: */
117: public String getName() {
118: return "POST";
119: }
120:
121: /**
122: * Returns <tt>true</tt> if there is a request body to be sent.
123: *
124: * <P>This method must be overwritten by sub-classes that implement
125: * alternative request content input methods
126: * </p>
127: *
128: * @return boolean
129: *
130: * @since 2.0beta1
131: */
132: protected boolean hasRequestContent() {
133: LOG.trace("enter PostMethod.hasRequestContent()");
134: if (!this .params.isEmpty()) {
135: return true;
136: } else {
137: return super .hasRequestContent();
138: }
139: }
140:
141: /**
142: * Clears request body.
143: *
144: * <p>This method must be overwritten by sub-classes that implement
145: * alternative request content input methods</p>
146: *
147: * @since 2.0beta1
148: */
149: protected void clearRequestBody() {
150: LOG.trace("enter PostMethod.clearRequestBody()");
151: this .params.clear();
152: super .clearRequestBody();
153: }
154:
155: /**
156: * Generates a request entity from the post parameters, if present. Calls
157: * {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set.
158: *
159: * @since 3.0
160: */
161: protected RequestEntity generateRequestEntity() {
162: if (!this .params.isEmpty()) {
163: // Use a ByteArrayRequestEntity instead of a StringRequestEntity.
164: // This is to avoid potential encoding issues. Form url encoded strings
165: // are ASCII by definition but the content type may not be. Treating the content
166: // as bytes allows us to keep the current charset without worrying about how
167: // this charset will effect the encoding of the form url encoded string.
168: String content = EncodingUtil.formUrlEncode(
169: getParameters(), getRequestCharSet());
170: ByteArrayRequestEntity entity = new ByteArrayRequestEntity(
171: EncodingUtil.getAsciiBytes(content),
172: FORM_URL_ENCODED_CONTENT_TYPE);
173: return entity;
174: } else {
175: return super .generateRequestEntity();
176: }
177: }
178:
179: /**
180: * Sets the value of parameter with parameterName to parameterValue. This method
181: * does not preserve the initial insertion order.
182: *
183: * @param parameterName name of the parameter
184: * @param parameterValue value of the parameter
185: *
186: * @since 2.0
187: */
188: public void setParameter(String parameterName, String parameterValue) {
189: LOG.trace("enter PostMethod.setParameter(String, String)");
190:
191: removeParameter(parameterName);
192: addParameter(parameterName, parameterValue);
193: }
194:
195: /**
196: * Gets the parameter of the specified name. If there exists more than one
197: * parameter with the name paramName, then only the first one is returned.
198: *
199: * @param paramName name of the parameter
200: *
201: * @return If a parameter exists with the name argument, the coresponding
202: * NameValuePair is returned. Otherwise null.
203: *
204: * @since 2.0
205: *
206: */
207: public NameValuePair getParameter(String paramName) {
208: LOG.trace("enter PostMethod.getParameter(String)");
209:
210: if (paramName == null) {
211: return null;
212: }
213:
214: Iterator iter = this .params.iterator();
215:
216: while (iter.hasNext()) {
217: NameValuePair parameter = (NameValuePair) iter.next();
218:
219: if (paramName.equals(parameter.getName())) {
220: return parameter;
221: }
222: }
223: return null;
224: }
225:
226: /**
227: * Gets the parameters currently added to the PostMethod. If there are no
228: * parameters, a valid array is returned with zero elements. The returned
229: * array object contains an array of pointers to the internal data
230: * members.
231: *
232: * @return An array of the current parameters
233: *
234: * @since 2.0
235: *
236: */
237: public NameValuePair[] getParameters() {
238: LOG.trace("enter PostMethod.getParameters()");
239:
240: int numPairs = this .params.size();
241: Object[] objectArr = this .params.toArray();
242: NameValuePair[] nvPairArr = new NameValuePair[numPairs];
243:
244: for (int i = 0; i < numPairs; i++) {
245: nvPairArr[i] = (NameValuePair) objectArr[i];
246: }
247:
248: return nvPairArr;
249: }
250:
251: /**
252: * Adds a new parameter to be used in the POST request body.
253: *
254: * @param paramName The parameter name to add.
255: * @param paramValue The parameter value to add.
256: *
257: * @throws IllegalArgumentException if either argument is null
258: *
259: * @since 1.0
260: */
261: public void addParameter(String paramName, String paramValue)
262: throws IllegalArgumentException {
263: LOG.trace("enter PostMethod.addParameter(String, String)");
264:
265: if ((paramName == null) || (paramValue == null)) {
266: throw new IllegalArgumentException(
267: "Arguments to addParameter(String, String) cannot be null");
268: }
269: super .clearRequestBody();
270: this .params.add(new NameValuePair(paramName, paramValue));
271: }
272:
273: /**
274: * Adds a new parameter to be used in the POST request body.
275: *
276: * @param param The parameter to add.
277: *
278: * @throws IllegalArgumentException if the argument is null or contains
279: * null values
280: *
281: * @since 2.0
282: */
283: public void addParameter(NameValuePair param)
284: throws IllegalArgumentException {
285: LOG.trace("enter PostMethod.addParameter(NameValuePair)");
286:
287: if (param == null) {
288: throw new IllegalArgumentException(
289: "NameValuePair may not be null");
290: }
291: addParameter(param.getName(), param.getValue());
292: }
293:
294: /**
295: * Adds an array of parameters to be used in the POST request body. Logs a
296: * warning if the parameters argument is null.
297: *
298: * @param parameters The array of parameters to add.
299: *
300: * @since 2.0
301: */
302: public void addParameters(NameValuePair[] parameters) {
303: LOG.trace("enter PostMethod.addParameters(NameValuePair[])");
304:
305: if (parameters == null) {
306: LOG.warn("Attempt to addParameters(null) ignored");
307: } else {
308: super .clearRequestBody();
309: for (int i = 0; i < parameters.length; i++) {
310: this .params.add(parameters[i]);
311: }
312: }
313: }
314:
315: /**
316: * Removes all parameters with the given paramName. If there is more than
317: * one parameter with the given paramName, all of them are removed. If
318: * there is just one, it is removed. If there are none, then the request
319: * is ignored.
320: *
321: * @param paramName The parameter name to remove.
322: *
323: * @return true if at least one parameter was removed
324: *
325: * @throws IllegalArgumentException When the parameter name passed is null
326: *
327: * @since 2.0
328: */
329: public boolean removeParameter(String paramName)
330: throws IllegalArgumentException {
331: LOG.trace("enter PostMethod.removeParameter(String)");
332:
333: if (paramName == null) {
334: throw new IllegalArgumentException(
335: "Argument passed to removeParameter(String) cannot be null");
336: }
337: boolean removed = false;
338: Iterator iter = this .params.iterator();
339:
340: while (iter.hasNext()) {
341: NameValuePair pair = (NameValuePair) iter.next();
342:
343: if (paramName.equals(pair.getName())) {
344: iter.remove();
345: removed = true;
346: }
347: }
348: return removed;
349: }
350:
351: /**
352: * Removes all parameter with the given paramName and paramValue. If there
353: * is more than one parameter with the given paramName, only one is
354: * removed. If there are none, then the request is ignored.
355: *
356: * @param paramName The parameter name to remove.
357: * @param paramValue The parameter value to remove.
358: *
359: * @return true if a parameter was removed.
360: *
361: * @throws IllegalArgumentException when param name or value are null
362: *
363: * @since 2.0
364: */
365: public boolean removeParameter(String paramName, String paramValue)
366: throws IllegalArgumentException {
367: LOG.trace("enter PostMethod.removeParameter(String, String)");
368:
369: if (paramName == null) {
370: throw new IllegalArgumentException(
371: "Parameter name may not be null");
372: }
373: if (paramValue == null) {
374: throw new IllegalArgumentException(
375: "Parameter value may not be null");
376: }
377:
378: Iterator iter = this .params.iterator();
379:
380: while (iter.hasNext()) {
381: NameValuePair pair = (NameValuePair) iter.next();
382:
383: if (paramName.equals(pair.getName())
384: && paramValue.equals(pair.getValue())) {
385: iter.remove();
386: return true;
387: }
388: }
389:
390: return false;
391: }
392:
393: /**
394: * Sets an array of parameters to be used in the POST request body
395: *
396: * @param parametersBody The array of parameters to add.
397: *
398: * @throws IllegalArgumentException when param parameters are null
399: *
400: * @since 2.0beta1
401: */
402: public void setRequestBody(NameValuePair[] parametersBody)
403: throws IllegalArgumentException {
404: LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])");
405:
406: if (parametersBody == null) {
407: throw new IllegalArgumentException(
408: "Array of parameters may not be null");
409: }
410: clearRequestBody();
411: addParameters(parametersBody);
412: }
413: }
|