You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Jonathan Asbell <ja...@i-2000.com> on 2001/06/09 15:39:46 UTC

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.


Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
Sorry, I should have said "If the bean goes away, then so does the only
reference you'll get to the file that holds the uploaded data". The FormFile
object, which contains the relevant information, will go away when the bean
goes away (unless you have another reference to it, of course). The FormFile
does not contain the actual uploaded data, just the name of the file it was
saved in.

--
Martin Cooper


----- Original Message -----
From: "Jonathan Asbell" <ja...@i-2000.com>
To: <st...@jakarta.apache.org>
Sent: Sunday, June 10, 2001 11:16 PM
Subject: Re: uploading file requires immediate serialization location?


> You wrote... "The uploaded data is stored in a temporary file somewhere on
> disk.....The bean is in either request or session scope..... If the bean
> goes away, then so does the file that holds the uploaded data."
>
> I thought you said the file was written to disk?  Thus the binary is not
in
> the bean.  Or is it that the FormFile has all this data and IT is in the
> bean.  So I end up with a file on disk that is in a state of not be
> associated with anything yet, and whos filename and input field names I
have
> lost when the bean went away.  Is that it?  If we are keeping the FormFile
> in the bean, in the session and the FormFile indeed does contain the
binary,
> than this is a bad thing.  We should at theleast kill the binary from the
> FormFile object so we CAN safely put it in the session.  (Dont know if I
> mentioned by weblogic croaks/freaks if the session has too much "k" in it.
>
> ----- Original Message -----
> From: "Martin Cooper" <ma...@tumbleweed.com>
> To: <st...@jakarta.apache.org>; "Jonathan Asbell"
<ja...@i-2000.com>
> Sent: Monday, June 11, 2001 1:55 AM
> Subject: Re: uploading file requires immediate serialization location?
>
>
> > String parameters are not written to a file. Only the bodies of file
> upload
> > parts are written to disk, and each one to a separate file. The files
are
> > written as the input stream (i.e. the request) is processed.
> >
> > Let's say your form has two fields, a textarea called 'myText' and a
file
> > input called 'myFile'. After you submit it, and Struts has populated
your
> > form bean, you will have:
> >
> > 1) The text from the textarea field is stored in the bean's 'myText'
> > property as a String.
> > 2) The uploaded data is stored in a temporary file somewhere on disk.
> > 3) The 'myFile' property on your bean, which has type FormFile, contains
> > information about the uploaded data (e.g. file name, content type,
etc.).
> >
> > The bean is in either request or session scope, as you defined it in
your
> > struts-config.xml file. If the bean goes away, then so does the file
that
> > holds the uploaded data.
> >
> > Hope this helps.
> >
> > --
> > Martin Cooper
> >
> >
> > ----- Original Message -----
> > From: "Jonathan Asbell" <ja...@i-2000.com>
> > To: <st...@jakarta.apache.org>
> > Sent: Sunday, June 10, 2001 10:48 PM
> > Subject: Re: uploading file requires immediate serialization location?
> >
> >
> > > So do you simultaneously write to a file while reading a String
> parameter
> > > when you process a form?  What parts of the multipart request do we
save
> > in
> > > the bean, and in what scope?
> > >
> > > ----- Original Message -----
> > > From: "Martin Cooper" <ma...@tumbleweed.com>
> > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > <ja...@i-2000.com>
> > > Sent: Monday, June 11, 2001 1:23 AM
> > > Subject: Re: uploading file requires immediate serialization location?
> > >
> > >
> > > > 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" <ja...@i-2000.com>
> > > > To: <st...@jakarta.apache.org>
> > > > 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" <ma...@tumbleweed.com>
> > > > > To: "Jonathan Asbell" <ja...@i-2000.com>
> > > > > Cc: <st...@jakarta.apache.org>
> > > > > 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" <ja...@i-2000.com>
> > > > > > To: "Martin Cooper" <ma...@tumbleweed.com>
> > > > > > 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" <ma...@tumbleweed.com>
> > > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > > <ja...@i-2000.com>
> > > > > > > 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" <ja...@i-2000.com>
> > > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > > 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" <ma...@tumbleweed.com>
> > > > > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > > > > <ja...@i-2000.com>
> > > > > > > > > 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" <ja...@i-2000.com>
> > > > > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > > > > 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.
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>



Re: uploading file requires immediate serialization location?

Posted by Jonathan Asbell <ja...@i-2000.com>.
You wrote... "The uploaded data is stored in a temporary file somewhere on
disk.....The bean is in either request or session scope..... If the bean
goes away, then so does the file that holds the uploaded data."

I thought you said the file was written to disk?  Thus the binary is not in
the bean.  Or is it that the FormFile has all this data and IT is in the
bean.  So I end up with a file on disk that is in a state of not be
associated with anything yet, and whos filename and input field names I have
lost when the bean went away.  Is that it?  If we are keeping the FormFile
in the bean, in the session and the FormFile indeed does contain the binary,
than this is a bad thing.  We should at theleast kill the binary from the
FormFile object so we CAN safely put it in the session.  (Dont know if I
mentioned by weblogic croaks/freaks if the session has too much "k" in it.

----- Original Message -----
From: "Martin Cooper" <ma...@tumbleweed.com>
To: <st...@jakarta.apache.org>; "Jonathan Asbell" <ja...@i-2000.com>
Sent: Monday, June 11, 2001 1:55 AM
Subject: Re: uploading file requires immediate serialization location?


> String parameters are not written to a file. Only the bodies of file
upload
> parts are written to disk, and each one to a separate file. The files are
> written as the input stream (i.e. the request) is processed.
>
> Let's say your form has two fields, a textarea called 'myText' and a file
> input called 'myFile'. After you submit it, and Struts has populated your
> form bean, you will have:
>
> 1) The text from the textarea field is stored in the bean's 'myText'
> property as a String.
> 2) The uploaded data is stored in a temporary file somewhere on disk.
> 3) The 'myFile' property on your bean, which has type FormFile, contains
> information about the uploaded data (e.g. file name, content type, etc.).
>
> The bean is in either request or session scope, as you defined it in your
> struts-config.xml file. If the bean goes away, then so does the file that
> holds the uploaded data.
>
> Hope this helps.
>
> --
> Martin Cooper
>
>
> ----- Original Message -----
> From: "Jonathan Asbell" <ja...@i-2000.com>
> To: <st...@jakarta.apache.org>
> Sent: Sunday, June 10, 2001 10:48 PM
> Subject: Re: uploading file requires immediate serialization location?
>
>
> > So do you simultaneously write to a file while reading a String
parameter
> > when you process a form?  What parts of the multipart request do we save
> in
> > the bean, and in what scope?
> >
> > ----- Original Message -----
> > From: "Martin Cooper" <ma...@tumbleweed.com>
> > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> <ja...@i-2000.com>
> > Sent: Monday, June 11, 2001 1:23 AM
> > Subject: Re: uploading file requires immediate serialization location?
> >
> >
> > > 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" <ja...@i-2000.com>
> > > To: <st...@jakarta.apache.org>
> > > 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" <ma...@tumbleweed.com>
> > > > To: "Jonathan Asbell" <ja...@i-2000.com>
> > > > Cc: <st...@jakarta.apache.org>
> > > > 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" <ja...@i-2000.com>
> > > > > To: "Martin Cooper" <ma...@tumbleweed.com>
> > > > > 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" <ma...@tumbleweed.com>
> > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > <ja...@i-2000.com>
> > > > > > 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" <ja...@i-2000.com>
> > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > 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" <ma...@tumbleweed.com>
> > > > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > > > <ja...@i-2000.com>
> > > > > > > > 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" <ja...@i-2000.com>
> > > > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > > > 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.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>


Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
String parameters are not written to a file. Only the bodies of file upload
parts are written to disk, and each one to a separate file. The files are
written as the input stream (i.e. the request) is processed.

Let's say your form has two fields, a textarea called 'myText' and a file
input called 'myFile'. After you submit it, and Struts has populated your
form bean, you will have:

1) The text from the textarea field is stored in the bean's 'myText'
property as a String.
2) The uploaded data is stored in a temporary file somewhere on disk.
3) The 'myFile' property on your bean, which has type FormFile, contains
information about the uploaded data (e.g. file name, content type, etc.).

The bean is in either request or session scope, as you defined it in your
struts-config.xml file. If the bean goes away, then so does the file that
holds the uploaded data.

Hope this helps.

--
Martin Cooper


----- Original Message -----
From: "Jonathan Asbell" <ja...@i-2000.com>
To: <st...@jakarta.apache.org>
Sent: Sunday, June 10, 2001 10:48 PM
Subject: Re: uploading file requires immediate serialization location?


> So do you simultaneously write to a file while reading a String parameter
> when you process a form?  What parts of the multipart request do we save
in
> the bean, and in what scope?
>
> ----- Original Message -----
> From: "Martin Cooper" <ma...@tumbleweed.com>
> To: <st...@jakarta.apache.org>; "Jonathan Asbell"
<ja...@i-2000.com>
> Sent: Monday, June 11, 2001 1:23 AM
> Subject: Re: uploading file requires immediate serialization location?
>
>
> > 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" <ja...@i-2000.com>
> > To: <st...@jakarta.apache.org>
> > 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" <ma...@tumbleweed.com>
> > > To: "Jonathan Asbell" <ja...@i-2000.com>
> > > Cc: <st...@jakarta.apache.org>
> > > 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" <ja...@i-2000.com>
> > > > To: "Martin Cooper" <ma...@tumbleweed.com>
> > > > 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" <ma...@tumbleweed.com>
> > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > <ja...@i-2000.com>
> > > > > 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" <ja...@i-2000.com>
> > > > > > To: <st...@jakarta.apache.org>
> > > > > > 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" <ma...@tumbleweed.com>
> > > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > > <ja...@i-2000.com>
> > > > > > > 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" <ja...@i-2000.com>
> > > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > > 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.
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>



Re: uploading file requires immediate serialization location?

Posted by Jonathan Asbell <ja...@i-2000.com>.
So do you simultaneously write to a file while reading a String parameter
when you process a form?  What parts of the multipart request do we save in
the bean, and in what scope?

----- Original Message -----
From: "Martin Cooper" <ma...@tumbleweed.com>
To: <st...@jakarta.apache.org>; "Jonathan Asbell" <ja...@i-2000.com>
Sent: Monday, June 11, 2001 1:23 AM
Subject: Re: uploading file requires immediate serialization location?


> 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" <ja...@i-2000.com>
> To: <st...@jakarta.apache.org>
> 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" <ma...@tumbleweed.com>
> > To: "Jonathan Asbell" <ja...@i-2000.com>
> > Cc: <st...@jakarta.apache.org>
> > 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" <ja...@i-2000.com>
> > > To: "Martin Cooper" <ma...@tumbleweed.com>
> > > 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" <ma...@tumbleweed.com>
> > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > <ja...@i-2000.com>
> > > > 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" <ja...@i-2000.com>
> > > > > To: <st...@jakarta.apache.org>
> > > > > 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" <ma...@tumbleweed.com>
> > > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > > <ja...@i-2000.com>
> > > > > > 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" <ja...@i-2000.com>
> > > > > > > To: <st...@jakarta.apache.org>
> > > > > > > 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.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>


Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
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" <ja...@i-2000.com>
To: <st...@jakarta.apache.org>
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" <ma...@tumbleweed.com>
> To: "Jonathan Asbell" <ja...@i-2000.com>
> Cc: <st...@jakarta.apache.org>
> 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" <ja...@i-2000.com>
> > To: "Martin Cooper" <ma...@tumbleweed.com>
> > 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" <ma...@tumbleweed.com>
> > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > <ja...@i-2000.com>
> > > 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" <ja...@i-2000.com>
> > > > To: <st...@jakarta.apache.org>
> > > > 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" <ma...@tumbleweed.com>
> > > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > > <ja...@i-2000.com>
> > > > > 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" <ja...@i-2000.com>
> > > > > > To: <st...@jakarta.apache.org>
> > > > > > 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.
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > >
> >
> >
>



Re: uploading file requires immediate serialization location?

Posted by Jonathan Asbell <ja...@i-2000.com>.
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" <ma...@tumbleweed.com>
To: "Jonathan Asbell" <ja...@i-2000.com>
Cc: <st...@jakarta.apache.org>
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" <ja...@i-2000.com>
> To: "Martin Cooper" <ma...@tumbleweed.com>
> 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" <ma...@tumbleweed.com>
> > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> <ja...@i-2000.com>
> > 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" <ja...@i-2000.com>
> > > To: <st...@jakarta.apache.org>
> > > 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" <ma...@tumbleweed.com>
> > > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > > <ja...@i-2000.com>
> > > > 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" <ja...@i-2000.com>
> > > > > To: <st...@jakarta.apache.org>
> > > > > 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.
> > > > >
> > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> >
>
>


Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
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" <ja...@i-2000.com>
To: "Martin Cooper" <ma...@tumbleweed.com>
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" <ma...@tumbleweed.com>
> To: <st...@jakarta.apache.org>; "Jonathan Asbell"
<ja...@i-2000.com>
> 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" <ja...@i-2000.com>
> > To: <st...@jakarta.apache.org>
> > 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" <ma...@tumbleweed.com>
> > > To: <st...@jakarta.apache.org>; "Jonathan Asbell"
> > <ja...@i-2000.com>
> > > 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" <ja...@i-2000.com>
> > > > To: <st...@jakarta.apache.org>
> > > > 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.
> > > >
> > > >
> > > >
> > > >
> > >
> >
> >
>



Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
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" <ja...@i-2000.com>
To: <st...@jakarta.apache.org>
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" <ma...@tumbleweed.com>
> To: <st...@jakarta.apache.org>; "Jonathan Asbell"
<ja...@i-2000.com>
> 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" <ja...@i-2000.com>
> > To: <st...@jakarta.apache.org>
> > 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.
> >
> >
> >
> >
>



Re: uploading file requires immediate serialization location?

Posted by Jonathan Asbell <ja...@i-2000.com>.
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" <ma...@tumbleweed.com>
To: <st...@jakarta.apache.org>; "Jonathan Asbell" <ja...@i-2000.com>
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" <ja...@i-2000.com>
> To: <st...@jakarta.apache.org>
> 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.
>
>
>
>


Re: uploading file requires immediate serialization location?

Posted by Martin Cooper <ma...@tumbleweed.com>.
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" <ja...@i-2000.com>
To: <st...@jakarta.apache.org>
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.