1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.apache.commons.httpclient.methods;
31
32 import java.util.Iterator;
33 import java.util.Vector;
34
35 import org.apache.commons.httpclient.NameValuePair;
36 import org.apache.commons.httpclient.util.EncodingUtil;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 /***
41 * Implements the HTTP POST method.
42 * <p>
43 * The HTTP POST method is defined in section 9.5 of
44 * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
45 * <blockquote>
46 * The POST method is used to request that the origin server accept the entity
47 * enclosed in the request as a new subordinate of the resource identified by
48 * the Request-URI in the Request-Line. POST is designed to allow a uniform
49 * method to cover the following functions:
50 * <ul>
51 * <li>Annotation of existing resources</li>
52 * <li>Posting a message to a bulletin board, newsgroup, mailing list, or
53 * similar group of articles</li>
54 * <li>Providing a block of data, such as the result of submitting a form,
55 * to a data-handling process</li>
56 * <li>Extending a database through an append operation</li>
57 * </ul>
58 * </blockquote>
59 * </p>
60 *
61 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
62 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
63 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
64 * @author Ortwin Gl???ck
65 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
66 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
67 *
68 * @version $Revision: 155418 $
69 * @since 1.0
70 */
71 public class PostMethod extends EntityEnclosingMethod {
72
73
74 /*** Log object for this class. */
75 private static final Log LOG = LogFactory.getLog(PostMethod.class);
76
77 /*** The Content-Type for www-form-urlencoded. */
78 public static final String FORM_URL_ENCODED_CONTENT_TYPE =
79 "application/x-www-form-urlencoded";
80
81 /***
82 * The buffered request body consisting of <code>NameValuePair</code>s.
83 */
84 private Vector params = new Vector();
85
86
87
88 /***
89 * No-arg constructor.
90 *
91 * @since 1.0
92 */
93 public PostMethod() {
94 super();
95 }
96
97 /***
98 * Constructor specifying a URI.
99 *
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
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 /***
123 * Returns <tt>true</tt> if there is a request body to be sent.
124 *
125 * <P>This method must be overwritten by sub-classes that implement
126 * alternative request content input methods
127 * </p>
128 *
129 * @return boolean
130 *
131 * @since 2.0beta1
132 */
133 protected boolean hasRequestContent() {
134 LOG.trace("enter PostMethod.hasRequestContent()");
135 if (!this.params.isEmpty()) {
136 return true;
137 } else {
138 return super.hasRequestContent();
139 }
140 }
141
142 /***
143 * Clears request body.
144 *
145 * <p>This method must be overwritten by sub-classes that implement
146 * alternative request content input methods</p>
147 *
148 * @since 2.0beta1
149 */
150 protected void clearRequestBody() {
151 LOG.trace("enter PostMethod.clearRequestBody()");
152 this.params.clear();
153 super.clearRequestBody();
154 }
155
156 /***
157 * Generates a request entity from the post parameters, if present. Calls
158 * {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set.
159 *
160 * @since 3.0
161 */
162 protected RequestEntity generateRequestEntity() {
163 if (!this.params.isEmpty()) {
164
165
166
167
168
169 String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet());
170 ByteArrayRequestEntity entity = new ByteArrayRequestEntity(
171 EncodingUtil.getAsciiBytes(content),
172 FORM_URL_ENCODED_CONTENT_TYPE
173 );
174 return entity;
175 } else {
176 return super.generateRequestEntity();
177 }
178 }
179
180 /***
181 * Sets the value of parameter with parameterName to parameterValue. This method
182 * does not preserve the initial insertion order.
183 *
184 * @param parameterName name of the parameter
185 * @param parameterValue value of the parameter
186 *
187 * @since 2.0
188 */
189 public void setParameter(String parameterName, String parameterValue) {
190 LOG.trace("enter PostMethod.setParameter(String, String)");
191
192 removeParameter(parameterName);
193 addParameter(parameterName, parameterValue);
194 }
195
196 /***
197 * Gets the parameter of the specified name. If there exists more than one
198 * parameter with the name paramName, then only the first one is returned.
199 *
200 * @param paramName name of the parameter
201 *
202 * @return If a parameter exists with the name argument, the coresponding
203 * NameValuePair is returned. Otherwise null.
204 *
205 * @since 2.0
206 *
207 */
208 public NameValuePair getParameter(String paramName) {
209 LOG.trace("enter PostMethod.getParameter(String)");
210
211 if (paramName == null) {
212 return null;
213 }
214
215 Iterator iter = this.params.iterator();
216
217 while (iter.hasNext()) {
218 NameValuePair parameter = (NameValuePair) iter.next();
219
220 if (paramName.equals(parameter.getName())) {
221 return parameter;
222 }
223 }
224 return null;
225 }
226
227 /***
228 * Gets the parameters currently added to the PostMethod. If there are no
229 * parameters, a valid array is returned with zero elements. The returned
230 * array object contains an array of pointers to the internal data
231 * members.
232 *
233 * @return An array of the current parameters
234 *
235 * @since 2.0
236 *
237 */
238 public NameValuePair[] getParameters() {
239 LOG.trace("enter PostMethod.getParameters()");
240
241 int numPairs = this.params.size();
242 Object[] objectArr = this.params.toArray();
243 NameValuePair[] nvPairArr = new NameValuePair[numPairs];
244
245 for (int i = 0; i < numPairs; i++) {
246 nvPairArr[i] = (NameValuePair) objectArr[i];
247 }
248
249 return nvPairArr;
250 }
251
252 /***
253 * Adds a new parameter to be used in the POST request body.
254 *
255 * @param paramName The parameter name to add.
256 * @param paramValue The parameter value to add.
257 *
258 * @throws IllegalArgumentException if either argument is null
259 *
260 * @since 1.0
261 */
262 public void addParameter(String paramName, String paramValue)
263 throws IllegalArgumentException {
264 LOG.trace("enter PostMethod.addParameter(String, String)");
265
266 if ((paramName == null) || (paramValue == null)) {
267 throw new IllegalArgumentException(
268 "Arguments to addParameter(String, String) cannot be null");
269 }
270 super.clearRequestBody();
271 this.params.add(new NameValuePair(paramName, paramValue));
272 }
273
274 /***
275 * Adds a new parameter to be used in the POST request body.
276 *
277 * @param param The parameter to add.
278 *
279 * @throws IllegalArgumentException if the argument is null or contains
280 * null values
281 *
282 * @since 2.0
283 */
284 public void addParameter(NameValuePair param)
285 throws IllegalArgumentException {
286 LOG.trace("enter PostMethod.addParameter(NameValuePair)");
287
288 if (param == null) {
289 throw new IllegalArgumentException("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("Parameter name may not be null");
371 }
372 if (paramValue == null) {
373 throw new IllegalArgumentException("Parameter value may not be null");
374 }
375
376 Iterator iter = this.params.iterator();
377
378 while (iter.hasNext()) {
379 NameValuePair pair = (NameValuePair) iter.next();
380
381 if (paramName.equals(pair.getName())
382 && paramValue.equals(pair.getValue())) {
383 iter.remove();
384 return true;
385 }
386 }
387
388 return false;
389 }
390
391 /***
392 * Sets an array of parameters to be used in the POST request body
393 *
394 * @param parametersBody The array of parameters to add.
395 *
396 * @throws IllegalArgumentException when param parameters are null
397 *
398 * @since 2.0beta1
399 */
400 public void setRequestBody(NameValuePair[] parametersBody)
401 throws IllegalArgumentException {
402 LOG.trace("enter PostMethod.setRequestBody(NameValuePair[])");
403
404 if (parametersBody == null) {
405 throw new IllegalArgumentException("Array of parameters may not be null");
406 }
407 clearRequestBody();
408 addParameters(parametersBody);
409 }
410 }