From: <jue...@li...> - 2003-02-24 15:22:51
|
Hi everybody, I'd like to communicate an idea that I've been thinking about for quite a while. Currently hanging around at home being a bit sick, this is a good way to use the time... ;-) Anyway, I've already raised the topic of utility libraries on the Wrox forum some time ago, and I've done some research since. The main issue is file upload aka multipart request handling. There are currently 2 noteworthy reusable upload libraries: - Jason Hunter's COS (com.oreilly.servlet): the classic, under Jason's "buy my book" license; - Jakarta's Commons FileUpload (currently 1.0 beta): a new alternative, under the Apache license. The latter is now the default implementation of Struts 1.1's MultipartRequestHandler (alternatively, Struts still has the old 1.0 implementation, the simple DiskMultipartRequestHandler). COS may be older and better tested, but Commons FileUpload is more sophisticated: For example, it can keep uploaded files smaller than a specified threshold in memory instead of writing everything temporarily to disk. My goal is to support file upload within Spring's web package, in a straightforward and pluggable way. The obvious way would be some multipart check in ControllerServlet's doService method that exchanges the standard HttpServletRequest with a wrapping MultipartServletRequest (an interface derived from HttpServletRequest) if it detects a multipart request. Controller implementations can check for a multipart request via "request instanceof MultipartServletRequest", or simply cast to the class if they expect one. The following proposal for Spring's multipart handler interfaces is obviously inspired by both COS' MultipartRequest and Commons FileUpload's FileItem classes, so don't blame me! ;-) It should be easy to write implementations for COS and Commons FileUpload that we could include out of the box. Of course, we are only allowed to include Commons FileUpload in a Spring distribution, in terms of license. Whoever wants to use COS could simply download it, add it to his web app libraries, and configure affected Spring controller servlets accordingly. The MultipartServletRequest interface needs to support getParameter and associated methods, to be able to handle simple parameters in a multipart request transparently, just like when dealing with a normal request. For file handling, I propose to add the following methods beyond HttpServletRequest, analogous to parameter handling: - MultipartFile getFile(String name)... returning a file descriptor for the specified file, or null - Map getFileMap()... returning a Map with file names as keys and MultipartFile instances as values - clearFileResources()... clearing all temporary file resources (automatically called by ControllerServlet after Controller processing) MultipartFile is an interface with the following methods: - InputStream getInputStream()... returning an input stream with the contents of the file - String getFileName()... returning the original file name given by the client - String getContentType()... returning the content type given by the client These should allow for both simple implementations and simple usage by custom controller implementations. The interfaces could even be used by JSPs, as the wrapped request will also be used when forwarding, although that is not recommended practice. Normally, a custom upload controller will evaluate the uploaded files and parameters, and transfer them to some application-specific storage location that could be a filesystem or a database. For application programmers, it is not important where the files are stored temporarily or if they are stored on disk at all, therefore the interfaces do not cover such aspects. Essentially, multipart handling should be as easy and transparent as possible. Finally, how will a ControllerServlet retrieve a MultipartServletRequest instance, using the toolkit of the application's choice? A straightforward Spring way would be to define a standard bean name "multipartResolver" (analogous to "viewResolver" and "localeResolver") that needs to implement the interface MultipartResolver: - MultipartServletRequest createMultipartRequest(HttpServletRequest request)... creating a wrapper - boolean hasMultipartContent(HttpServletRequest request)... checking the content type Of course, ControllerServlet should simply ignore multipart handling when there's no "multipartResolver" bean, maybe log a warning on initialization. What do you think? If we settle on the proposal, I could implement it promptly (right after locale resolution). I definitely consider file upload a 1.0 issue, as both Struts and WebWork have built-in support for it. Juergen P.S.: Concerning 2 other utility issues: For FTP and other Internet protocols that are not supported with J2SE, there's a new alternative too: Jakarta's Commons Net. I guess we won't need special support for it withing Spring. HTML escaping/unescaping: This is so fundamental and yet so simple that I've always wondered about the lack of standard support for it. Not even Struts 1.1 does include a respective utility class. So everyone seems to write his own... I'd like to include a HtmlUtils class providing static htmlEscape and htmlUnescape methods in Spring's web.util package, if no one objects. |