|
From: Trevor C. <pr...@se...> - 2003-10-14 13:06:09
|
It is interesting seeing your arguments flip 180 degrees in a few =
paragraphs, but you're not alone there. I find the same thing, that =
talking helps me find my own solutions.
As far as the implementation goes, the changes are perfect. It's a lot =
cleaner than my original version (no coupling with DispatcherServlet or =
property editors), but we still have the benefit of custom property =
handling.
I've migrated our project from the original multipart to the new =
version, and everything works great. My code uses "standard" handling =
(byte[] and MultipartFile) as well as the custom property editors. I've =
also subclassed the CommonsMultipartResolver to provide some additional =
functionality in our app, and that works perfect as well.
I think we have a winner :)
Trevor D. Cook
-----Original Message-----
From: j=C3=BCrgen h=C3=B6ller [werk3AT] =
[mailto:jue...@we...]
Sent: October 14, 2003 1:13 AM
To: j=C3=BCrgen h=C3=B6ller [werk3AT]; Trevor Cook; Spring Developers
Subject: Re: [Springframework-developer] Multipart File Handling
P.S.: Funny how the direction of an own argument can change in the =
course of a single email ;-) Of course, I was talking about =
PropertyEditor's setAsText (and the indirection with String values that =
match field names) in the first paragraph, and haven't had realized at =
that time that there was the completely different setValue option too...
=20
Juergen
=20
-----Ursprngliche Nachricht-----=20
Von: j rgen hller [werk3AT]=20
Gesendet: Di 14.10.2003 01:26=20
An: Trevor Cook; Spring Developers=20
Cc:=20
Betreff: Re: [Springframework-developer] Multipart File Handling
=09
=09
Trevor,
=09
Sorry if I've been a bit eager in terms of getting rid of the =
PropertyEditor stuff for multipart files. I strongly believe that the =
JavaBeans PropertyEditor is not appropriate for multipart files though, =
as it is about converting *String* parameters to other types. This is =
fine for standard ServletRequest parameters that come in as String =
values and need to be bound to arbitrary properties of command objects. =
Multipart files on the other hand are by their very nature complex =
objects; they do not have a natural String representation.
=09
The previous mechanism of binding multipart files via PropertyEditor =
required MultipartHttpServletRequest's getParameter method to return the =
field name as value a la getParameter("myfield") -> "myfield", so that a =
PropertyEditor that can just see the value would be able to identify the =
field name and invoke MultipartHttpServletRequest's getFile("myfield") =
to return the MultipartFile instance. This *is* a workaround, as it is =
not at all natural to have getParameter return the field name as value =
in case of a multipart file.
=09
ServletRequestDataBinder is not a bad place for binding multipart =
files, given that our MultipartHttpServletRequest is a generic interface =
that resides in the non-DispatcherServlet-specific web.multipart package =
now. I agree that it isn't generally preferable to hardcode binding =
options, but I've initially felt that there aren't any other meaningful =
conversions than a MultipartFile itself or a byte[] as value of a =
command bean property. Note that you can always override =
BaseCommandController's onBindAndValidate to perform *custom* binding.
=09
-----
=09
On second thought, I agree that a pluggable conversion mechanism is =
preferable. I've just reworked the multipart binding into a =
PropertyEditor mechanism again, but with a different implementation =
pattern: ServletRequestDataBinder simply binds the file map returned by =
MultipartHttpServletRequest.getFileMap as property values. This means =
that bean properties of type MultipartFile can be populated directly, =
without conversion. Other types go through the PropertyEditor mechanism, =
but via calling setValue(Object) instead of setAsText(String).
=09
ByteArrayMultipartFileEditor and StringMultipartFileEditor implement =
setValue to transform the given MultipartFile instance into either a =
byte array or a String, the latter with configurable charset. Note than =
none of these needs a MultipartHttpServletRequest: They receive the =
MultipartFile instances bound as property values by =
ServletRequestDataBinder. Those two custom editors need to be registered =
with ServletRequestDataBinder via registerCustomEditor, preferably for =
specific fields to avoid conflicts with other fields of the type byte =
array or String.
=09
I consider this a good solution, more flexible than the hardcoded =
binding, but also cleaner than the PropertyEditor indirection with =
String parameters. Thanks for pointing at the issue again! Overriding =
PropertyEditor's setValue is generally a nice way to convert from =
non-String values to the required type; I didn't think of it at first, =
and I had to tweak BeanWrapperImpl a bit to allow for it. I hope you =
like the current solution too; does it fulfil your requirements now?
=09
Juergen
=09
=09
=09
-----Urspr ngliche Nachricht-----
Von: Trevor Cook [mailto:pr...@se...]
Gesendet: Mo 13.10.2003 22:22
An: jrgen h ller [werk3AT]; Spring Developers
Cc:
Betreff: RE: [Springframework-developer] Multipart File =
Handling
=20
=20
=09
<juergen>
Furthermore, I've dropped the previous PropertyEditors support, =
and the associated requirement for file parameters having to be =
available as normal parameters with the field name as value. That seemed =
like a workaround; instead, I've added explicit detection to =
ServletRequestDataBinder, which is now able to bind file parameters as =
MultipartFile or byte[], depending on the type of the target bean =
property. I've not reintroduced binding the original file name to a =
String property, as I can't see the value of that feature.
</juergen>
=20
No problem dropping the String <> filename, I wasn't sure if =
that would be useful or not.
=20
I do have a problem with dropping the PropertyEditors support, =
since in my mind it removes flexibility and consistency.
=20
Treating all the data (simple text fields or files) as =
parameters seems to make a lot more sense to me since you can then treat =
every piece of data the same (instead of having to handle parameters and =
files seperately). If the implementation was a little clumsy I =
apologize, but the concept was not a workaround but a goal to allow the =
user to be able to treat all data in the same manner.
=20
The issue of flexibility is due to the "explicit detection to =
ServletRequestDataBinder". In the previous implementation and the =
current one, files were automatically bound to an object based on the =
target properties type. The difference was that you could override it =
with a custom property editor (in the BaseCommandController initBinder =
method, for example). Under the current implementation, there is no way =
to override how the file is attached to the bean. Do you (or anybody =
else) have any suggestions on how to override the default Spring =
handling (currently hard-coded in ServletRequestDataBinder), or any =
ideas of how to change the implementation to allow this custom handling?
=20
Trevor D. Cook
=20
=20
=09
=
N=18HYXu=16w=1A+m>xZ=1AzMx'=17z{=08=1CB=105z??')rH?q=07z??J=07jgzx?G?q=07=
z?X?~zwX??=07jgz=20
---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.525 / Virus Database: 322 - Release Date: 09/10/2003
|