Date: 2005-03-02T12:20:44
Editor: DakotaJack
Wiki: Apache Struts Wiki
Page: StrutsUpload
URL: http://wiki.apache.org/struts/StrutsUpload
no comment
Change Log:
------------------------------------------------------------------------------
@@ -1,26 +1,40 @@
-== Introduction ==
+== Overview ==
-This wiki page is an attempt to open some serious dialogue on providing a
multipart request API in the Struts framework that will work for the default
Struts upload application as well as alternative implementations and
applications. Presently alternative implementations have to forego using
ActionForm because the populate method of RequestUtils necessitates using the
default MultipartRequestWrapper and the default MultipartRequestHandler.
+This is about Struts v1.2.6 and forward multipart requests. The following
classes are suggested as a basis for allowing Struts users/developers to
implement their own file upload applications. The object of suggesting these
classes is to make the use of !ActionForm available to users/developers who
want to do something more than the present default file upload application
packaged with Struts allows but maintaining backward compatibility.
-I have suggested using an alternative MultipartRequestHandler which will
promote alternative ideas and have supplanted the MultipartRequestWrapper with
a MultipartData interface. If the committers want to continue passing the
MultipartRequestWrapper to the Action, then this can be accomplished by passing
the implementation of the MultipartData interface to the
MultipartRequestWrapper.
+These classes, I believe, with minor revisions to the Struts framework allow
this. If these classes seem remotely acceptable to those who decide such
things, I will go on to code suggested changes to the framework, which really
are not much.
-I would strongly suggest, however, not wrapping the multipart request and
getting the appropriate multipart data from the ActionForm alone.
+The last three classes are example implementations of the first three
interfaces and the !MultipartUtil. Any comments or suggestions are welcomed.
-Below you will find suggested alternatives to the existing wrapper and
handler. The suggestion is to provide two Globals fields to identify the
MultipartData and MultipartRequestHandler which would be set in the mapping for
whatever UploadAction subclass of Action is implemented.
+=== Framework Code ===
-The point of all this is shown in the implementation of the
MultipartRequestHandler below. As you can see, this alternative, while costing
nothing, allows us to make our applications as sophisticated as we want by
varying the input parameters to the handleRequest(Object []) method of the
MultipartRequestHandler. In our example, we (1) pass in information with
"maxFileSize" and "repositoryPath" to tell the handler what to do; (2) pass in
Maps "parameterNames" and "files" as well as the "encoding" paramenter to be
initialized by the handler; (3) pass in a List of monitors to be embedded in
wrappers of the commons file upload package FileItem, DiskFileUpload, etc.
+ 1. !MultipartFile Interface
+ 2. !MultipartData Interface
+ 3. !MultipartHandler Interface
+ 4. !MultipartUtil Class
-== Suggested Code ==
+=== Sample Implementation Code ===
-=== MultipartRequestHandler ===
+ 1. !UploadMultipartFile Class
+ 2. !UploadMultipartData Class
+ 3. !UploadMultipartHandler Class
+
+== Code ==
+
+=== MultipartFile ===
{{{
-public interface MultipartRequestHandler {
- public void handleRequest(Object [] params) throws IOException;
- public void setServlet(ActionServlet servlet);
- public void setMapping(ActionMapping mapping);
- public ActionServlet getServlet();
- public ActionMapping getMapping();
+public interface MultipartFile
+ extends Serializable {
+ public long getSize();
+ public void setSize(long fileSize);
+ public String getName();
+ public void setName(String fileName);
+ public String getContentType();
+ public void setContentType(String fileContentType);
+ public byte[] getData();
+ public InputStream getInputStream();
+ public void reset();
}
}}}
@@ -35,6 +49,18 @@
}
}}}
+=== MultipartHandler ===
+
+{{{
+public interface MultipartHandler {
+ public void handleRequest(Object [] params) throws IOException;
+ public void setServlet(ActionServlet servlet);
+ public void setMapping(ActionMapping mapping);
+ public ActionServlet getServlet();
+ public ActionMapping getMapping();
+}
+}}}
+
=== MultipartUtil ===
{{{
@@ -60,6 +86,98 @@
}
}}}
+=== UploadMultipartFile ===
+
+{{{
+public class UploadMultipartFile
+ implements MultipartFile {
+ private String fileContentType;
+ private String fileName;
+ private long fileSize;
+ private FileItem fi;
+
+ public UploadMultipartFile() {
+ }
+
+ public UploadMultipartFile(FileItem fi) {
+ this.fi = fi;
+ }
+
+ public UploadMultipartFile(String fileName,
+ String fileContentType,
+ long fileSize) {
+ this.fileSize = -1L;
+ this.fileName = fileName;
+ this.fileContentType = fileContentType;
+ this.fileSize = fileSize;
+ }
+
+ public long getSize() {
+ return fileSize;
+ }
+
+ public void setSize(long fileSize) {
+ this.fileSize = fileSize;
+ }
+
+ public String getName() {
+ return fileName;
+ }
+
+ public void setName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getContentType() {
+ return fileContentType;
+ }
+
+ public void setContentType(String fileContentType) {
+ this.fileContentType = fileContentType;
+ }
+
+ public byte[] getData() {
+ InputStream is = getInputStream();
+ if(is != null) {
+ int i = (int)getSize();
+ if(i > 0) {
+ byte data0[] = new byte[i];
+ try {
+ is.read(data0);
+ is.close();
+ } catch(IOException ioe) { }
+ return data0;
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ public void reset() {
+ if(this.fi != null)
+ this.fi.delete();
+ }
+
+ public InputStream getInputStream() {
+ if(fi == null) {
+ return null;
+ }
+
+ try {
+ return new BufferedInputStream(fi.getInputStream());
+ } catch (IOException ioe) {
+ return null;
+ }
+ }
+
+ public FileItem getFileItem() {
+ return fi;
+ }
+}
+}}}
+
=== UploadMultipartData ===
{{{
@@ -82,7 +200,7 @@
parameterNames = Collections.synchronizedMap(new HashMap(89));
files = Collections.synchronizedMap(new HashMap(89));
- MultipartRequestHandler handler = new UploadMultipartRequestHandler();
+ MultipartHandler handler = new UploadMultipartHandler();
Object [] objects = new Object [] { req,monitors,
new Integer(fileSizeLimit),
@@ -121,15 +239,15 @@
}
}}}
-=== UploadMultipartRequestHandler ===
+=== UploadMultipartHandler ===
{{{
-public class UploadMultipartRequestHandler
- implements MultipartRequestHandler {
+public class UploadMultipartHandler
+ implements MultipartHandler {
private ActionMapping mapping;
private ActionServlet servlet;
- public UploadMultipartRequestHandler() {
+ public UploadMultipartHandler() {
}
public void handleRequest(Object [] params)
@@ -200,7 +318,7 @@
} else {
String name = fi.getName();
if(name != null) {
- FormFile uf = new UploadFormFile(fi);
+ MultipartFile uf = new UploadMultipartFile(fi);
name = name.replace('\\', '/');
int j = name.lastIndexOf("/");
@@ -208,9 +326,9 @@
name = name.substring(j + 1, name.length());
}
- uf.setFileName(name);
- uf.setFileContentType(fi.getContentType());
- uf.setFileSize(fi.getSize());
+ uf.setName(name);
+ uf.setContentType(fi.getContentType());
+ uf.setSize(fi.getSize());
files.put(fieldName, uf);
}
}
@@ -232,58 +350,5 @@
public void setMapping(ActionMapping mapping) {
this.mapping = mapping;
}
-}
-}}}
-
-
-=== FormFile ===
-
-{{{
-public abstract class FormFile
- implements Serializable {
- private String fileContentType;
- private String fileName;
- private long fileSize;
-
- public FormFile(String fileName,
- String fileContentType,
- long fileSize) {
- this.fileSize = -1L;
- this.fileName = fileName;
- this.fileContentType = fileContentType;
- this.fileSize = fileSize;
- }
-
- public FormFile() {
- this(null, null, -1L);
- }
-
- public long getFileSize() {
- return fileSize;
- }
-
- public void setFileSize(long fileSize) {
- this.fileSize = fileSize;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public String getFileContentType() {
- return fileContentType;
- }
-
- public void setFileContentType(String fileContentType) {
- this.fileContentType = fileContentType;
- }
-
- public abstract byte[] getFileData();
- public abstract InputStream getFileInputStream();
- public abstract void reset();
}
}}}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]