Yes, I think you've got it. Just to be clear, though, when you say "we need
to examine the sections in the header ...", the "we" here is Struts - you
don't need to do anything in your application. Struts makes getParameter()
et all work for multipart requests as well as regular requests.

What you are seeing in the packages you've looked at is the parsing of a
MIME part. The fields in a multipart/form-data request each conform to the
specification for a MIME part, and they are separated by a boundary, which
is a line containing a pattern defined in a header at the top of the
request.

Each MIME part consists of a sequence of MIME headers, followed by a blank
line, followed by the data for that MIME part, known as the body. A MIME
header takes the form "header-name: value" - for example, "Content-type:
text/plain". The body is just a bunch of data that conforms to the
statements made about it in the headers.

Every field in a multipart request is encoded this way. So where a regular
query using GET might contain a query string like this:

...&author=Martin&...

a multipart request would represent the same query parameter like this:

-----------------------------0123456789--
Content-disposition: form-data; name="author"

Martin
-----------------------------0123456789--

For a file upload, the difference is only that the Content-disposition
header will include a file name, and the data can be binary if necessary.

When a multipart handler processes a request, it is reading the data from an
input stream provided by the container. Typically, for regular query
parameters, it will store the value in a hash table. For file parameters, it
will store the data in a file and retain information about that file. The
Struts implementation uses the FormFile interface to provide access to that
information.

A multipart implementation could do whatever it wanted to with the data
provided from a file upload. Although the Content-disposition header may
specify a file name, there is no requirement to store that data as a file.
One implementation that would make sense would be to define a size
threshold, and store uploaded objects below that size in memory, while
writing larger ones to disk.

Regarding form beans and binary data, there is no reason why a field in a
form bean cannot be a byte array. However, by itself that is not very
useful, hence the FormFile interface. If you'll notice, that interface does
in fact have a getFileData() method, which will give you the uploaded data
as a byte array. In the current implementation, what that actually does is
load the contents of the file into memory and hand you back that memory. And
there you have binary data in a form field.

Hope this helps.

--
Martin Cooper


----- Original Message -----
From: "Jonathan Asbell" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Sunday, June 10, 2001 1:19 PM
Subject: Re: uploading file requires immediate serialization location?


> Martin, you seem to understand this subject well, so let me take a shot
and
> tell me if I am correct:
>
> A multi-part request is a request, but a different one.  That is, with a
> regular request things have been abstracted for us nicely with
> "getParameter" etc., but a request submitted as multipart is not handled
> nicely for us by the servlet spec and is a whole different animal.  This
> type of request needs to be handled uniquely (though I dont understand why
> the servlet spec does not have standard abstractions for it), because it
may
> contain binary non-text content accompanied by regular content.  In such a
> request we need to examine the sections in the header and parse for
certain
> values we are expecting to separate out the regular text values submitted
> from the binary parts, and then handle the binary parts.
>
> Things I still dont get:
> In all packages I have examined that handle multipart requests, there is
> always a notion of looking for the line ": ", then looking for the blank
> line after that, and then reading in binary values that follow the blank
> line up until the "boundry" which is a String in a known format (see link
> below).  What I dont understand is what are our options in handling this
> binary stuff which is not text.  Most packages I have seen write it to a
> file.  I'm not sure if there is a way to save a binary object at all, let
> alone save it in a filed value in a bean.  How do you store a binary
object
> in a field?
>
> ==============
> REFERENCE
> ==============
> For those interested see this article:
> www.onjava.com/lpt/a//onjava/2001/04/05/upload.html
> Available servlet packages http://www.servlets.com/cos/index.html
>
>
>
> ----- Original Message -----
> From: "Martin Cooper" <[EMAIL PROTECTED]>
> To: "Jonathan Asbell" <[EMAIL PROTECTED]>
> Cc: <[EMAIL PROTECTED]>
> Sent: Sunday, June 10, 2001 3:01 PM
> Subject: Re: uploading file requires immediate serialization location?
>
>
> > Good question. What you are really asking is "what does the <html:file>
> tag
> > do?".
> >
> > Struts will generate an <input type="file" ... > tag, where the value of
> the
> > 'name' attribute is taken from the 'property' attribute of your
> <html:file>
> > tag. It will also generate a 'value' attribute. Looking at the source
> code,
> > it seems that the valueof the 'value' attribute will be the result of
> > calling toString() on the FormFile object. Since that object doesn't
> > override toString(), the result will be nothing useful. On the other
hand,
> > browsers usually ignore the 'value' attribute anyway.
> >
> > At this point, the original uploaded file is still on the disk, and will
> > remain there until the form is resubmitted. Then it will be deleted as a
> > part of setting up for parsing the new multipart data.
> >
> > Hope this helps.
> >
> > --
> > Martin Cooper
> >
> >
> > ----- Original Message -----
> > From: "Jonathan Asbell" <[EMAIL PROTECTED]>
> > To: "Martin Cooper" <[EMAIL PROTECTED]>
> > Sent: Sunday, June 10, 2001 5:47 AM
> > Subject: Re: uploading file requires immediate serialization location?
> >
> >
> > > Great explanation Martin. Thank you.  So what you really have said is
> that
> > > the stream contents gets turned into a FormFile object.  Ok.  Now the
> big
> > > question.  You know when a form is not valid it gets sent beack to the
> > > client as strings which pre-populate the form fields.  How will this
> occur
> > > in the case of a file input?
> > >
> > >
> > > ----- Original Message -----
> > > From: "Martin Cooper" <[EMAIL PROTECTED]>
> > > To: <[EMAIL PROTECTED]>; "Jonathan Asbell"
> > <[EMAIL PROTECTED]>
> > > Sent: Sunday, June 10, 2001 12:20 AM
> > > Subject: Re: uploading file requires immediate serialization location?
> > >
> > >
> > > > Let me see if I can describe the process.
> > > >
> > > > 1. Check to see if the request should be treated as multipart (i.e.
> > > content
> > > > type is multipart/form-data and method is POST). If not, carry on as
> > > normal.
> > > > 2. Find the multipart handler or instantiate one, set it on the form
> > bean,
> > > > and call it to handle the request.
> > > > 2a. Iterate over the fields (parts) in the request.
> > > > 2a1. If the current part is not a file, store it as a String.
> > > > 2a2. If the current part is a file (according to the
> Content-Disposition
> > > > header), create a new file in the temp directory, stream the content
> of
> > > the
> > > > part to that file, create a new object which implements FormFile,
and
> > > store
> > > > the file data in it.
> > > > 2b. Turn the set of fields into something that looks like regular
> > request
> > > > parameters.
> > > > 3. Populate the ActionForm instance from the set of request
> parameters.
> > > > Here, the value of a file parameter has type FormFile, so it matches
a
> > > > setter on the form bean that takes a FormFile as a parameter.
> > > >
> > > > That's the gist of it, although there are some other nitty gritty
> > details.
> > > > Almost all of this happens inside the code that populates the form
> bean
> > > from
> > > > request parameters.
> > > >
> > > > It appears (from my reading of the source, anyway) that the
temporary
> > > files
> > > > will not be automatically deleted until another request comes in
that
> > uses
> > > > the same form bean instance, or until the form bean instance goes
> away.
> > > > Given that, I would recommend calling
setMultipartRequestHandler(null)
> > > from
> > > > your form bean's reset() method if you keep your beans in session
> scope.
> > > >
> > > > The part you are interested in, I believe, is 2a2 above.
> Unfortunately,
> > > that
> > > > code is buried inside an iterator class, so you can't override just
> that
> > > > piece. I assume what you would want is that the data is kept in
memory
> > > > instead of to a file. Interestingly, I believe the original
> > implementation
> > > > did this, but it was changed to use files because of potential
memory
> > > > problems with large uploads.
> > > >
> > > > Hope this helps.
> > > >
> > > > --
> > > > Martin Cooper
> > > >
> > > >
> > > > ----- Original Message -----
> > > > From: "Jonathan Asbell" <[EMAIL PROTECTED]>
> > > > To: <[EMAIL PROTECTED]>
> > > > Sent: Saturday, June 09, 2001 8:11 PM
> > > > Subject: Re: uploading file requires immediate serialization
location?
> > > >
> > > >
> > > > > Hello Martin.  So is it POSSIBLE to save binary data in a bean?
> What
> > > does
> > > > > struts do?  These are my real questions.  If I have a form which
> > besides
> > > > > fields, has an uploaded file, how does the bean actually handle
the
> > > file?
> > > > > Is there a conceptual step by step you can give me.  How does the
> > > > ActionForm
> > > > > save (and validate) the binary data sent via input type "file".
> > > > >
> > > > >
> > > > > ----- Original Message -----
> > > > > From: "Martin Cooper" <[EMAIL PROTECTED]>
> > > > > To: <[EMAIL PROTECTED]>; "Jonathan Asbell"
> > > > <[EMAIL PROTECTED]>
> > > > > Sent: Saturday, June 09, 2001 10:55 PM
> > > > > Subject: Re: uploading file requires immediate serialization
> location?
> > > > >
> > > > >
> > > > > > Internally to Struts, multipart handling is provided through an
> > > > interface,
> > > > > > MultipartRequestHandler. In Struts 1.0, the only supplied
> > > implementation
> > > > > of
> > > > > > this interface is DiskMultipartRequestHandler, which, as you
might
> > > > expect,
> > > > > > writes "file" parts to disk as it encounters them.
> > > > > >
> > > > > > Struts does allow you to configure the multipart handler to use,
> by
> > > > > > specifying the class name in the multipartClass init-param for
> your
> > > web
> > > > > app.
> > > > > > This allows you to provide your own implementation if you want
to
> > > > > (although
> > > > > > this is no small task).
> > > > > >
> > > > > > --
> > > > > > Martin Cooper
> > > > > >
> > > > > >
> > > > > > ----- Original Message -----
> > > > > > From: "Jonathan Asbell" <[EMAIL PROTECTED]>
> > > > > > To: <[EMAIL PROTECTED]>
> > > > > > Sent: Saturday, June 09, 2001 6:39 AM
> > > > > > Subject: uploading file requires immediate serialization
location?
> > > > > >
> > > > > >
> > > > > > Hello all.
> > > > > > I am just trying to understand an aspect of a multipart request.
> > When
> > > > > > you submit after using an input of type "file", do you have to
> > provide
> > > > > > an immediate location for the file to be serialized to, or can
you
> > > store
> > > > > > it in a java object (in a bean's field) as a binary object until
> you
> > > are
> > > > > > ready to serialize it.  The reason is that I want to hold a jpeg
> in
> > a
> > > > > > bean until the person completes the last page of the form, and
> THEN
> > > > > > serialize it.
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>


Reply via email to