Multipart File Upload in Servlet 3.0 Using Multipart Config

Java EE introduced built in support for handling multipart MIME file uploads in Servlet 3.0 (Java EE 6). Web servers based on PHP and ASP.NET have provided this functionality for some time now, saving having to use other third party libraries for the multipart “heavy lifting”. However, it carries a performance overhead for the container to parse the request and hence is an optional extension enabled on a servlet-by-servlet basis and needs to tell the container explicitly that the Servlet expect requests that conform to the multipart/form-data MIME type if you need to use this functionality. If you enable this functionality on a servlet, the container will make additional methods available on an HttpServletRequest to get all parts available on a request and also to get one of those parts passing in its name.  

The demo note next will give you a better understanding of this note: http://javajee.com/demo-multipart-file-upload-in-servlet-30-using-multip....

 

You can tell the container that instances of the Servlet expect requests that conform to the multipart/form-data MIME type through the annotation @MultipartConfig.

All of the attribute elements of the annotation @MultipartConfig are optional:

  • fileSizeThreshold

    • The size threshold after which the file will be written to disk

    • The fileSizeThreshold is a byte limit above which the file will be saved to a temporary file on the hard drive, rather than cached in RAM. This helps to reduce applications RAM footprint for large file uploads.

    • Unless you intend to save all the uploads to the hard drive, you may wish to set this larger than the 0 default to avoid using slower disk –based access when reading the file contents.

    • Files with byte sizes above this value will be cached in the directory given by the location element- or the value of the javax.servlet.context.tempdir environment variable in the container (if location is omitted). If the location is given as a relative path, it will be relative to that tempdir set in the container.

    • Default is 0 which means files will be immediately written without caching.

    • Type=int

  • location

    • The directory location where files will be stored

    • If the location is given as a relative path, it will be relative to that tempdir set in the container (value of the javax.servlet.context.tempdir environment variable).

    • Default is “”.

    • Type=java.lang.String

  • maxFileSize

    • The maximum size allowed for uploaded files.

    • The default is -1L, which means unlimited.

    • Type=long

  • maxRequestSize

    • The maximum size allowed for multipart/form-data requests.

    • The default is -1L, which means unlimited.

    • Type=long

You can also configure this through the web.xml using servlet element’s subelement multipart-config and its subelements. For more details, refer to http://javajee.com/the-deployment-descriptor-webxml.

 

Additional methods made available on the HttpServletRequest to handle parts are:

  • Collection<Part> getParts()

    • Gets all the Part components of this request, provided that it is of type multipart/form-data.

    • If this request is of type multipart/form-data, but does not contain any Part components, the returned Collection will be empty.

    • Any changes to the returned Collection will not affect this HttpServletRequest.

  • Part getPart(String name)

    • Gets the Part with the given name when passed the name of a Part.

    • Returns the Part with the given name, or null if this request is of type multipart/form-data, but does not contain the requested Part.

Both these methods throws IOException if an I/O error occurred during the retrieval of the Part components of this request, ServletException if this request is not of type multipart/form-data or IllegalStateException if the request body is larger than maxRequestSize, or any Part in the request is larger than maxFileSize

 

An implementation of the Part interface represents a part or form item that was received within a multipart/form-data POST request.

  • void delete()

    • Deletes the underlying storage for a file item, including deleting any associated temporary disk file.

  • String getContentType()

    • Gets the content type of this part.

  • String getHeader(java.lang.String name)

    • Returns the value of the specified mime header as a String.

  • Collection<String> getHeaderNames()

    • Gets the header names of this Part.

  • Collection<String> getHeaders(String name)

    • Gets the values of the Part header with the given name.

  • InputStream getInputStream()

    • Gets the content of this part as an InputStream

  • String getName()

    • Gets the name of this part

  • long getSize()

    • Returns the size of this fille.

  • void write(String fileName)

    • A convenience method to write this uploaded item to disk.

    • If the uploaded file has been cached to the file system, then this typically allow the container to simply rename that temporary file to the location specified, rather than copying all of the underlying data, thus gaining a significant performance benefit.

    • However, this method is not guaranteed to succeed if called more than once for the same part.

Currently there is no convenience method to get the original filename of the uploaded file while uploading. So you will have to write your own method that gets the content-disposition header value and parse it to find the filename. Multipart uploads generated from HTML form has Parts which have a Content Disposition header set to form-data.

<Add-Example-Using-tcpmon-or-wireshark>

 

You have to make some changes at the form (client html side) to send the request as multipart/form-data. By using the @MultipartConfig annotation or the multipart-config DD element, you are telling the container that you are expecting a request of type multipart/form-data. A ServletException will be thrown if this request is not of type multipart/form-data.  The form data set is always encoded according to the content type specified by the enctype attribute of the FORM element.  To send the request as multipart/form-data, the enctype attribute must be supplied and set to multipart/form-data, so that no characters are encoded. Other possible values for the enctype attribute are application/x-www-form-urlencoded (default) and text/plain. The application/x-www-form-urlencoded (default) value denotes that All characters are encoded before sent (spaces are converted to "+" symbols, and special characters are converted to ASCII HEX values). The text/plain value denotes that spaces are converted to "+" symbols, but no special characters are encoded.

 

Multipart uploads generated from HTML form may also have one or more Parts which have a Content Disposition header set to form-data that do not represent file uploads. These will contain the other non-file variables supplied by an HTML form. For Example, free form text boxes, sets of checkboxes or radio buttons, etc. These form variables and their values are all available via the standard ServletRequest getParameter() and getParameterValues() methods.

 

References

https://docs.oracle.com/javaee/6/api/javax/servlet/http/Part.html

http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html

http://www.w3schools.com/tags/att_form_enctype.asp

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!