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