java.lang.Object
org.bzdev.net.FormDataIterator
- All Implemented Interfaces:
Iterator<InputStream>
Iterator to read input streams that provide data using the
multipart/form-data media type.
The embedded HTTP server handles POST requests by providing an
input stream containing some data. HTML forms in particular will
generate such a stream using the multipart/form-data media type.
When implementing a subclass of WebMap
,
given an instance of WebMap.RequestInfo
,
requestInfo
, one will typically use the following
design pattern:
If the content-type header's valueInputStream is = requestInfo.getDecodedInputStream(); String mediatype = requestInfo.getFromHeader("content-type", null); if (mediatype.equalsIgnoreCase("multipart/form-data")) { String boundary = requestHeader.getFromHeader("content-type", "boundary"); FormDataInterator it = new FormDataIterator(is, boundary); while (it.hasNext()) { InputStream cis = it.next(); ... cis.close(); } }
CTYPE
, and the input stream
is
containing the form's content, are available, then
the following design pattern can be used:
HeaderOps headerOps = HeaderOps.newInstance(); headerOps.set("content-type", CTYPE); String boundary = headerOps.getFirst("content-type", false) .get("boundary"); FormDataIterator it = new FormDataIterator(is, boundary); while (it.hasNext()) { InputStream cis = it.next(); ... it.close(); }
Notes:
- There is an HTML convention that forms with an element whose
name is "_charset_" contains the default charset for files whose
media type is text/plain. To support this convention, if a
the content type is text/plain and a charset parameter is not
provided, the default charset is returned by
getCharset()
. The default charset can be set by callingsetDefaultCharset(Charset)
. to follow this convention, an entry whose name is "_charset_" should have its stream read and then used to set the default charset. - If multiple files are being transferred for a single form field, the latest standard, (RFC 7578), requires that all the files use entities with the same name, and the 'filename' parameter can be used to distinguish them. Older software may provide a nested multipart-mixed part. To handle this deprecated usage, the user can simply process the input stream for this form field as an object whose type is multipart/mixed.
- While this class implements the
Iterator
interface, there is a restriction on its use: after the methodnext()
has been called, the stream returned must either be read to its end or closed beforehasNext()
is called. Otherwise anIllegalStateException
will be thrown.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionGet the charset for the current entryGet the value for the content-type header for the current entry.Get the file name for the current entry.Get the headers provided for the current entry.Get the media type, excluding its parameters, for the current entrygetName()
Get the name for the current entry.boolean
hasNext()
Determine if their are more entries to process.next()
Get the next entry.void
setDefaultCharset
(Charset charset) Set the default character set for this object.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface java.util.Iterator
forEachRemaining, remove
-
Constructor Details
-
FormDataIterator
Constructor.- Parameters:
is
- an input stream containing the multipart/form-data objectboundary
- the boundary, typically obtained by reading the 'boundary' parameter of a multipart/form-data media type- Throws:
IOException
- an IO error occurred
-
-
Method Details
-
setDefaultCharset
Set the default character set for this object.- Parameters:
charset
- the character set; null for the UTF-8 default
-
hasNext
Determine if their are more entries to process.Note: if the
InputStream
returned bynext()
has not been read fully and if such a stream has not been explicitly closed, an exception will be thrown- Specified by:
hasNext
in interfaceIterator<InputStream>
- Returns:
- true if there are more entries; false otherwise
- Throws:
IllegalStateException
- this method cannot be called when the input stream returned by next() has not been read completely or explicitly closed.
-
next
Get the next entry. Note: if theInputStream
returned by this method has not been read fully and if such a stream has not been explicitly closed, an exception will be thrown whenhasNext()
is called.- Specified by:
next
in interfaceIterator<InputStream>
- Returns:
- an input stream containing the data for the next entry
-
getHeaders
Get the headers provided for the current entry. These will typically be a "content-disposition" header and an optional content-type header.- Returns:
- the headers
-
getName
Get the name for the current entry. This will be the same as the name of a control in an HTML form when HTML forms are used. The name is provided in a "content-disposition" header.- Returns:
- the name; null if there is no header or the name is missing
-
getFileName
Get the file name for the current entry. When provided, this will typically be the name of a file on a file system accessed by whatever process initiated a POST method. The file name is provided in a "content-disposition" header.- Returns:
- the name; null if there is no header or the name is missing
-
getContentType
Get the value for the content-type header for the current entry.- Returns:
- the full content-type header; null if there is not one
-
getMediaType
Get the media type, excluding its parameters, for the current entry- Returns:
- the media type; null if a media type was not provided
-
getCharset
Get the charset for the current entry- Returns:
- the charset provided by a "content-type" header; a default charset if there is no content-type header
-