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
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$
70 * @since 1.0
71 */
72 public class PostMethod extends EntityEnclosingMethod {
73
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
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
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
166
167
168
169
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 }