# Class MultipartRequest

java.lang.Object
com.codename1.io.ConnectionRequest
com.codename1.io.MultipartRequest

All Implemented Interfaces:
  `IOProgressListener`

public class MultipartRequest extends ConnectionRequest

A multipart post request allows a developer to submit large binary data files to the server in a multipart mime post request. This is a standard method for large binary file uploads to webservers and data services.

The sample code below includes both the client code using the upload capabilities as well as a simple sample servlet that can accept multipart data:

    // File: MultipartClientSample.java
    MultipartRequest request = new MultipartRequest();
    request.setUrl(url);
    request.addData("myFileName", fullPathToFile, "text/plain");
    NetworkManager.getInstance().addToQueue(request);

    // File: UploadServlet.java
    @WebServlet(name = "UploadServlet", urlPatterns = {"/upload"})
    @MultipartConfig(fileSizeThreshold = 1024 * 1024 * 100, // 10 MB
            maxFileSize = 1024 * 1024 * 150, // 50 MB
            maxRequestSize = 1024 * 1024 * 200)      // 100 MB
    public class UploadServlet extends HttpServlet {
    @Override
        public void doPost(HttpServletRequest req, HttpServletResponse res)
                throws ServletException, IOException {
            Collection parts = req.getParts();
            Part data = parts.iterator().next();
            try(InputStream is = data.getInputStream()) {}
                // store or do something with the input stream
            }
        }
    }

The sample code below demonstrates uploading to the filestack.com API.

    public void pictureUpload(final Callback resultURL) {
        String picture = Capture.capturePhoto(1024, -1);
        if(picture!=null){
            String filestack = "https://www.filestackapi.com/api/store/S3?key=MY_KEY&filename=myPicture.jpg";
            MultipartRequest request = new MultipartRequest() {
               protected void readResponse(InputStream input) throws IOException  {
                  JSONParser jp = new JSONParser();
                  Map result = jp.parseJSON(new InputStreamReader(input, "UTF-8"));
                  String url = (String)result.get("url");
                  if(url == null) {
                     resultURL.onError(null, null, 1, result.toString());
                     return;
                  }
                  resultURL.onSucess(url);
               }
            };
            request.setUrl(filestack);
            try {
                request.addData("fileUpload", picture, "image/jpeg");
                request.setFilename("fileUpload", "myPicture.jpg");
                NetworkManager.getInstance().addToQueue(request);
            } catch(IOException err) {
                err.printStackTrace();
            }
        }
    }

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from class ConnectionRequest

  `ConnectionRequest.CachingMode, ConnectionRequest.SSLCertificate`

- ## Field Summary

  ### Fields inherited from class ConnectionRequest

  `PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_REDUNDANT`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `MultipartRequest()`
  Initialize variables

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addArgument(String name, String value)`
  Add an argument to the request response
  `void`
  `addArgument(String name, String[] value)`
  Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key
  `void`
  `addArgumentNoEncoding(String key, String value)`
  Add an argument to the request response without encoding it, this is useful for arguments which are already encoded
  `void`
  `addArgumentNoEncoding(String key, String[] value)`
  Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key, notice that this doesn't implicitly encode the value
  `void`
  `addArgumentNoEncodingArray(String key, String... value)`
  Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key, notice that this doesn't implicitly encode the value
  `void`
  `addData(String name, byte[] data, String mimeType)`
  Adds a binary argument to the arguments
  `void`
  `addData(String name, InputStream data, long dataSize, String mimeType)`
  Adds a binary argument to the arguments, notice the input stream will be read only during submission
  `void`
  `addData(String name, String filePath, String mimeType)`
  Adds a binary argument to the arguments
  `protected void`
  `buildRequestBody(OutputStream os)`
  Invoked when send body is true, by default sends the request arguments based on "POST" conventions
  `protected long`
  `calculateContentLength()`
  `boolean`
  `equals(Object o)`
  Indicates whether some other object is "equal to" this one.
  `String`
  `getBoundary()`
  Returns the boundary string which is normally generated based on system time
  `int`
  `getContentLength()`
  Returns the content length header value
  `int`
  `hashCode()`
  Returns a hash code value for the object.
  `protected void`
  `initConnection(Object connection)`
  Invoked to initialize HTTP headers, cookies etc.
  `boolean`
  `isBase64Binaries()`
  Set to true to encode binary data as base 64
  `static boolean`
  `isLeaveInputStreamsOpen()`
  Special flag to keep input stream files open after they are read
  `boolean`
  `isManualRedirect()`
  By default redirect responses (302 etc.) are handled manually in multipart requests
  `boolean`
  `onRedirect(String url)`
  This is a callback method that been called when there is a redirect.
  `void`
  `setBase64Binaries(boolean base64Binaries)`
  Set to true to encode binary data as base 64
  `void`
  `setBoundary(String boundary)`
  Sets the boundary string, normally you don't need this method.
  `static void`
  `setCanFlushStream(boolean flush)`
  Sending large files requires flushing the writer once in a while to prevent Out Of Memory Errors, Some J2ME implementation are not able to flush the streams causing the upload to fail.
  `void`
  `setFilename(String arg, String filename)`
  Sets the filename for the given argument
  `static void`
  `setLeaveInputStreamsOpen(boolean aLeaveInputStreamsOpen)`
  Special flag to keep input stream files open after they are read
  `void`
  `setManualRedirect(boolean autoRedirect)`
  By default redirect responses (302 etc.) are handled manually in multipart requests, set this to false to handle the redirect.

  ### Methods inherited from class ConnectionRequest

  `addArgument, addArgumentArray, addArguments, addExceptionListener, addRequestHeader, addResponseCodeListener, addResponseListener, cacheUnmodified, canGetSSLCertificates, checkSSLCertificates, cookieReceived, cookieSent, createRequestURL, downloadImageToFileSystem, downloadImageToFileSystem, downloadImageToFileSystem, downloadImageToFileSystem, downloadImageToFileSystem, downloadImageToFileSystem, downloadImageToStorage, downloadImageToStorage, downloadImageToStorage, downloadImageToStorage, downloadImageToStorage, downloadImageToStorage, fetchJSON, fetchJSONAsync, fireResponseListener, getCachedData, getCacheMode, getContentType, getCookieHeader, getDefaultCacheMode, getDefaultUserAgent, getDestinationFile, getDestinationStorage, getDisposeOnCompletion, getHeader, getHeaderFieldNames, getHeaders, getHttpMethod, getPriority, getReadTimeout, getRequestBody, getRequestBodyData, getResponseCode, getResponseContentType, getResponseData, getResponseErrorMessage, getResposeCode, getShowOnInit, getSilentRetryCount, getSSLCertificates, getTimeout, getUrl, getUserAgent, getYield, handleErrorResponseCode, handleException, handleIOException, handleRuntimeException, hasResponseListeners, initCookieHeader, ioStreamUpdate, isCheckSSLCertificates, isCookiesEnabled, isCookiesEnabledDefault, isDefaultFollowRedirects, isDuplicateSupported, isFailSilently, isFollowRedirects, isHandleErrorCodesInGlobalErrorHandler, isInsecure, isKilled, isNativeCookieSharingSupported, isPausable, isPaused, isPost, isReadRequest, isReadResponseForErrors, isReadResponseForErrorsDefault, isReadTimeoutSupported, isRedirecting, isWriteRequest, kill, pause, postResponse, purgeCache, purgeCacheDirectory, readErrorCodeHeaders, readHeaders, readResponse, removeAllArguments, removeArgument, removeExceptionListener, removeResponseCodeListener, removeResponseListener, resume, retry, setCacheMode, setCheckSSLCertificates, setChunkedStreamingMode, setContentType, setCookieHeader, setCookiesEnabled, setCookiesEnabledDefault, setDefaultCacheMode, setDefaultFollowRedirects, setDefaultUserAgent, setDestinationFile, setDestinationStorage, setDisposeOnCompletion, setDuplicateSupported, setFailSilently, setFollowRedirects, setHandleErrorCodesInGlobalErrorHandler, setHttpMethod, setInsecure, setKilled, setPaused, setPost, setPriority, setReadRequest, setReadResponseForErrors, setReadResponseForErrorsDefault, setReadTimeout, setRequestBody, setRequestBody, setShowOnInit, setSilentRetryCount, setTimeout, setUrl, setUseNativeCookieStore, setUserAgent, setWriteRequest, shouldAutoCloseResponse, shouldConvertPostToGetOnRedirect, shouldStop, shouldWriteUTFAsGetBytes, validate`

  ### Methods inherited from class Object

  `clone, getClass, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### MultipartRequest

    public MultipartRequest()
    Initialize variables

- ## Method Details

  - ### isLeaveInputStreamsOpen

    public static boolean isLeaveInputStreamsOpen()

    Special flag to keep input stream files open after they are read

    ###### Returns

    the leaveInputStreamsOpen

  - ### setLeaveInputStreamsOpen

    public static void setLeaveInputStreamsOpen(boolean aLeaveInputStreamsOpen)

    Special flag to keep input stream files open after they are read

    ###### Parameters

    - `aLeaveInputStreamsOpen`: the leaveInputStreamsOpen to set

  - ### setCanFlushStream

    public static void setCanFlushStream(boolean flush)
    Sending large files requires flushing the writer once in a while to prevent Out Of Memory Errors, Some J2ME implementation are not able to flush the streams causing the upload to fail. This method can indicate to the upload to not use the flushing mechanism.

  - ### getBoundary

    public String getBoundary()

    Returns the boundary string which is normally generated based on system time

    ###### Returns

    the multipart boundary string

  - ### setBoundary

    public void setBoundary(String boundary)

    Sets the boundary string, normally you don't need this method. Its useful to workaround server issues only. Notice that this method must be invoked before adding any elements.

    ###### Parameters

    - `boundary`: the boundary string

  - ### initConnection

    protected void initConnection(Object connection)
    Description copied from class: `ConnectionRequest`

    Invoked to initialize HTTP headers, cookies etc.

    ###### Parameters

    - `connection`: the connection object
    Overrides:
      `initConnection` in class `ConnectionRequest`

  - ### addData

    public void addData(String name, byte[] data, String mimeType)

    Adds a binary argument to the arguments

    ###### Parameters

    - `name`: the name of the data

    - `data`: the data as bytes

    - `mimeType`: the mime type for the content

  - ### addData

    public void addData(String name, String filePath, String mimeType) throws java.io.IOException

    Adds a binary argument to the arguments

    ###### Parameters

    - `name`: the name of the file data

    - `filePath`: the path of the file to upload

    - `mimeType`: the mime type for the content

    ###### Throws

    - `IOException`: if the file cannot be opened
    Throws:
      `java.io.IOException`

  - ### addData

    public void addData(String name, InputStream data, long dataSize, String mimeType)

    Adds a binary argument to the arguments, notice the input stream will be read only during submission

    ###### Parameters

    - `name`: the name of the data

    - `data`: the data stream

    - `dataSize`: @param dataSize the byte size of the data stream, if the data stream is a file the file size can be obtained using the FileSystemStorage.getInstance().getLength(file) method

    - `mimeType`: the mime type for the content

  - ### setFilename

    public void setFilename(String arg, String filename)

    Sets the filename for the given argument

    ###### Parameters

    - `arg`: the argument name

    - `filename`: the file name

  - ### addArgumentNoEncoding

    public void addArgumentNoEncoding(String key, String value)

    Add an argument to the request response without encoding it, this is useful for arguments which are already encoded

    ###### Parameters

    - `key`: the key of the argument

    - `value`: the value for the argument

    Overrides:
      `addArgumentNoEncoding` in class `ConnectionRequest`

  - ### addArgumentNoEncoding

    public void addArgumentNoEncoding(String key, String[] value)

    Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key, notice that this doesn't implicitly encode the value

    ###### Parameters

    - `key`: the key of the argument

    - `value`: the value for the argument

    Overrides:
      `addArgumentNoEncoding` in class `ConnectionRequest`

  - ### addArgumentNoEncodingArray

    public void addArgumentNoEncodingArray(String key, String... value)

    Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key, notice that this doesn't implicitly encode the value

    ###### Parameters

    - `key`: the key of the argument

    - `value`: the value for the argument

    Overrides:
      `addArgumentNoEncodingArray` in class `ConnectionRequest`

  - ### addArgument

    public void addArgument(String name, String[] value)

    Add an argument to the request response as an array of elements, this will trigger multiple request entries with the same key

    ###### Parameters

    - `key`: the key of the argument

    - `value`: the value for the argument

    Overrides:
      `addArgument` in class `ConnectionRequest`

  - ### addArgument

    public void addArgument(String name, String value)

    Add an argument to the request response

    ###### Parameters

    - `key`: the key of the argument

    - `value`: the value for the argument

    Overrides:
      `addArgument` in class `ConnectionRequest`

  - ### calculateContentLength

    protected long calculateContentLength()

  - ### buildRequestBody

    protected void buildRequestBody(OutputStream os) throws java.io.IOException

    Invoked when send body is true, by default sends the request arguments based on "POST" conventions

    ###### Parameters

    - `os`: output stream of the body
    Overrides:
      `buildRequestBody` in class `ConnectionRequest`
    Throws:
      `java.io.IOException`

  - ### getContentLength

    public int getContentLength()
    Description copied from class: `ConnectionRequest`

    Returns the content length header value

    ###### Returns

    the content length

    Overrides:
      `getContentLength` in class `ConnectionRequest`

  - ### onRedirect

    public boolean onRedirect(String url)
    Description copied from class: `ConnectionRequest`

    This is a callback method that been called when there is a redirect. IMPORTANT this feature doesn't work on all platforms and currently doesn't work on iOS which always implicitly redirects

    ###### Parameters

    - `url`: the url to be redirected

    ###### Returns

    true if the implementation would like to handle this by itself

    Overrides:
      `onRedirect` in class `ConnectionRequest`

  - ### isManualRedirect

    public boolean isManualRedirect()

    By default redirect responses (302 etc.) are handled manually in multipart requests

    ###### Returns

    the autoRedirect

  - ### setManualRedirect

    public void setManualRedirect(boolean autoRedirect)

    By default redirect responses (302 etc.) are handled manually in multipart requests, set this to false to handle the redirect. Notice that a redirect converts a post to a get.

    ###### Parameters

    - `autoRedirect`: the autoRedirect to set

  - ### isBase64Binaries

    public boolean isBase64Binaries()

    Set to true to encode binary data as base 64

    ###### Returns

    the base64Binaries

  - ### setBase64Binaries

    public void setBase64Binaries(boolean base64Binaries)

    Set to true to encode binary data as base 64

    ###### Parameters

    - `base64Binaries`: the base64Binaries to set

  - ### equals

    public boolean equals(Object o)
    Description copied from class: `ConnectionRequest`
    Indicates whether some other object is "equal to" this one. The equals method implements an equivalence relation: It is reflexive: for any reference value x, x.equals(x) should return true. It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified. For any non-null reference value x, x.equals(null) should return false. The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).
    Overrides:
      `equals` in class `ConnectionRequest`

  - ### hashCode

    public int hashCode()
    Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable. The general contract of hashCode is: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
    Overrides:
      `hashCode` in class `ConnectionRequest`