View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v 1.17.2.2 2003/12/14 22:41:37 mbecke Exp $ 3 * $Revision: 1.17.2.2 $ 4 * $Date: 2003/12/14 22:41:37 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 2002-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 64 package org.apache.commons.httpclient.methods; 65 66 import java.io.File; 67 import java.io.FileNotFoundException; 68 import java.io.IOException; 69 import java.io.OutputStream; 70 import java.util.ArrayList; 71 import java.util.List; 72 73 import org.apache.commons.httpclient.HttpConnection; 74 import org.apache.commons.httpclient.HttpException; 75 import org.apache.commons.httpclient.HttpState; 76 import org.apache.commons.httpclient.methods.multipart.FilePart; 77 import org.apache.commons.httpclient.methods.multipart.Part; 78 import org.apache.commons.httpclient.methods.multipart.StringPart; 79 import org.apache.commons.logging.Log; 80 import org.apache.commons.logging.LogFactory; 81 82 /*** 83 * Implements the HTTP multipart POST method. 84 * <p> 85 * The HTTP multipart POST method is defined in section 3.3 of 86 * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC1867</a>: 87 * <blockquote> 88 * The media-type multipart/form-data follows the rules of all multipart 89 * MIME data streams as outlined in RFC 1521. The multipart/form-data contains 90 * a series of parts. Each part is expected to contain a content-disposition 91 * header where the value is "form-data" and a name attribute specifies 92 * the field name within the form, e.g., 'content-disposition: form-data; 93 * name="xxxxx"', where xxxxx is the field name corresponding to that field. 94 * Field names originally in non-ASCII character sets may be encoded using 95 * the method outlined in RFC 1522. 96 * </blockquote> 97 * </p> 98 * <p> 99 * 100 * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a> 101 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> 102 * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a> 103 * @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a> 104 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 105 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 106 * 107 * @since 2.0 108 */ 109 public class MultipartPostMethod extends ExpectContinueMethod { 110 111 /*** The Content-Type for multipart/form-data. */ 112 public static final String MULTIPART_FORM_CONTENT_TYPE = 113 "multipart/form-data"; 114 115 /*** Log object for this class. */ 116 private static final Log LOG = LogFactory.getLog(MultipartPostMethod.class); 117 118 /*** The parameters for this method */ 119 private final List parameters = new ArrayList(); 120 121 /*** 122 * No-arg constructor. 123 */ 124 public MultipartPostMethod() { 125 super(); 126 } 127 128 /*** 129 * Constructor specifying a URI. 130 * 131 * @param uri either an absolute or relative URI 132 */ 133 public MultipartPostMethod(String uri) { 134 super(uri); 135 } 136 137 /*** 138 * Constructor specifying a URI and tempDir. 139 * 140 * @param uri either an absolute or relative URI 141 * @param tempDir directory to store temp files in 142 */ 143 public MultipartPostMethod(String uri, String tempDir) { 144 super(uri, tempDir); 145 } 146 147 /*** 148 * Constructor specifying a URI, tempDir and tempFile. 149 * 150 * @param uri either an absolute or relative URI 151 * @param tempDir directory to store temp files in 152 * @param tempFile file to store temporary data in 153 */ 154 public MultipartPostMethod(String uri, String tempDir, String tempFile) { 155 super(uri, tempDir, tempFile); 156 } 157 158 /*** 159 * Returns <tt>true</tt> 160 * 161 * @return <tt>true</tt> 162 * 163 * @since 2.0beta1 164 */ 165 protected boolean hasRequestContent() { 166 return true; 167 } 168 169 /*** 170 * Returns <tt>"POST"</tt>. 171 * @return <tt>"POST"</tt> 172 */ 173 public String getName() { 174 return "POST"; 175 } 176 177 /*** 178 * Adds a text field part 179 * 180 * @param parameterName The name of the parameter. 181 * @param parameterValue The value of the parameter. 182 */ 183 public void addParameter(String parameterName, String parameterValue) { 184 LOG.trace("enter addParameter(String parameterName, String parameterValue)"); 185 Part param = new StringPart(parameterName, parameterValue); 186 parameters.add(param); 187 } 188 189 /*** 190 * Adds a binary file part 191 * 192 * @param parameterName The name of the parameter 193 * @param parameterFile The name of the file. 194 * @throws FileNotFoundException If the file cannot be found. 195 */ 196 public void addParameter(String parameterName, File parameterFile) 197 throws FileNotFoundException { 198 LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " 199 + "File parameterFile)"); 200 Part param = new FilePart(parameterName, parameterFile); 201 parameters.add(param); 202 } 203 204 /*** 205 * Adds a binary file part with the given file name 206 * 207 * @param parameterName The name of the parameter 208 * @param fileName The file name 209 * @param parameterFile The file 210 * @throws FileNotFoundException If the file cannot be found. 211 */ 212 public void addParameter(String parameterName, String fileName, File parameterFile) 213 throws FileNotFoundException { 214 LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " 215 + "String fileName, File parameterFile)"); 216 Part param = new FilePart(parameterName, fileName, parameterFile); 217 parameters.add(param); 218 } 219 220 /*** 221 * Adds a part. 222 * 223 * @param part The part to add. 224 */ 225 public void addPart (final Part part) { 226 LOG.trace("enter addPart(Part part)"); 227 parameters.add(part); 228 } 229 230 /*** 231 * Returns all parts. 232 * 233 * @return an array of containing all parts 234 */ 235 public Part[] getParts() { 236 return (Part[]) parameters.toArray(new Part[parameters.size()]); 237 } 238 /*** 239 * Adds <tt>Content Type: multipart/form-data</tt> header in addition 240 * to the "standard" set of headers 241 * 242 * @param state the {@link HttpState state} information associated with this method 243 * @param conn the {@link HttpConnection connection} used to execute 244 * this HTTP method 245 * 246 * @throws IOException if an I/O (transport) error occurs 247 * @throws HttpException if a protocol exception occurs. 248 * @throws HttpRecoverableException if a recoverable transport error occurs. 249 * Usually this kind of exceptions can be recovered from by 250 * retrying the HTTP method 251 */ 252 protected void addRequestHeaders(HttpState state, HttpConnection conn) 253 throws IOException, HttpException { 254 LOG.trace("enter MultipartPostMethod.addRequestHeaders(HttpState state, " 255 + "HttpConnection conn)"); 256 super.addRequestHeaders(state, conn); 257 258 if (!parameters.isEmpty()) { 259 StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE); 260 if (Part.getBoundary() != null) { 261 buffer.append("; boundary="); 262 buffer.append(Part.getBoundary()); 263 } 264 setRequestHeader("Content-Type", buffer.toString()); 265 } 266 } 267 268 /*** 269 * Writes the request body to the given {@link HttpConnection connection}. 270 * 271 * @param state the {@link HttpState state} information associated with this method 272 * @param conn the {@link HttpConnection connection} used to execute 273 * this HTTP method 274 * 275 * @return <tt>true</tt> 276 * 277 * @throws IOException if an I/O (transport) error occurs 278 * @throws HttpException if a protocol exception occurs. 279 * @throws HttpRecoverableException if a recoverable transport error occurs. 280 * Usually this kind of exceptions can be recovered from by 281 * retrying the HTTP method 282 */ 283 protected boolean writeRequestBody(HttpState state, HttpConnection conn) 284 throws IOException, HttpException { 285 LOG.trace("enter MultipartPostMethod.writeRequestBody(HttpState state, " 286 + "HttpConnection conn)"); 287 OutputStream out = conn.getRequestOutputStream(); 288 Part.sendParts(out, getParts()); 289 return true; 290 } 291 292 /*** 293 * <p>Return the length of the request body.</p> 294 * 295 * <p>Once this method has been invoked, the request parameters cannot be 296 * altered until the method is {@link #recycle recycled}.</p> 297 * 298 * @return The request content length. 299 */ 300 protected int getRequestContentLength() { 301 LOG.trace("enter MultipartPostMethod.getRequestContentLength()"); 302 try { 303 long len = Part.getLengthOfParts(getParts()); 304 // Chop the length to the max int value. 305 if (len <= Integer.MAX_VALUE) { 306 return (int) len; 307 } else { 308 return (Integer.MAX_VALUE); 309 } 310 } catch (IOException e) { 311 // Can't throw an IOException and still override 312 throw new RuntimeException(e.toString()); 313 } 314 } 315 316 317 /*** 318 * Recycles the HTTP method so that it can be used again. 319 * Note that all of the instance variables will be reset 320 * once this method has been called. This method will also 321 * release the connection being used by this HTTP method. 322 * 323 * @see #releaseConnection() 324 * 325 */ 326 public void recycle() { 327 LOG.trace("enter MultipartPostMethod.recycle()"); 328 super.recycle(); 329 parameters.clear(); 330 } 331 }

This page was automatically generated by Maven