Since PAW 0.51 file upload sizes are no longer restricted. This restriction has been removed by changing the code of the underlying Brazil framework.
This post shows how file upload can be implemented.
A ready to install ZIP file containig all the code is available at the end of the post.
Since PAW 0.51 requests with content-type
multipart/form-data are handled differently. The post request parameters are not handled automatically and processing is left to the application. The InputStream of the request can be accessed by using the instance variabel
request.in.
The example consists of two files. One is the html file containing the form which allows the upload of two files.
The second file is the xhtml file containing the code to save the uploaded files to the
/sdcard directory of the Android device.
To make the handling of the multipart form data easier the class
MultipartStream from the
Apache Commons Fileupload package has been added to PAW.
Actually this is an old version of the class which has no dependencies at all.
The html which contains the form is quite simple:
<html>
<head>
<title>File Upload</title>
<link rel="stylesheet" href="css/default.css">
</head>
<body>
<h2>File Upload Demo</h2>
<p>
Uploads files to /sdcard...
</p>
<form action="fup.xhtml" method="post" enctype="multipart/form-data" >
File to upload: <input name="upfile1" type="file"><br>
File to upload: <input name="upfile2" type="file"><br>
<input value="Upload" type="submit">
</form>
</body>
</html>
The second file performs the following steps to save the files:
- Extract the boundary string from the content-type.
- Constructs a MultipartStream object.
- Skips the preamble. This ignores all data until the boundary is reached.
- Reads the parts until it finds a file. If a file is found it extracts the filename and stores the file in the /sdcard directory.
- If the part contains no file, the part's body is skipped.
There is a nice article that discribes this in more detail on
oreillynet.com:
Parsing form-data multiparts
So now here is the code:
<html>
<head>
<title>File Upload</title>
<link rel="stylesheet" href="css/default.css">
</head>
<body>
<bsh>
import org.paw.util.*;
import org.apache.commons.fileupload.*;
outDir = "/sdcard/fup";
files = new ArrayList();
type = (String) request.headers.get("content-type");
if (type != null &&type.startsWith("multipart/form-data")) {
try {
// Get the boundary string
boundaryIndex = type.indexOf("boundary=");
byte[] boundary = (type.substring(boundaryIndex + 9)).getBytes();
// Construct a MultiPartStream with request.in as InputStream
MultipartStream multipartStream = new MultipartStream(request.in, boundary);
boolean nextPart = multipartStream.skipPreamble();
// Loop through all parts
while(nextPart) {
headers = multipartStream.readHeaders();
// If part is a file, save it to disk. Otherwise skip it.
if(headers.contains("filename=\"")) {
// Get filename
filename = headers.substring(headers.indexOf("filename=") + 10);
filename = filename.substring(0, filename.indexOf("\""));
// If filename is not empty save content to filesystem
if(filename.length() > 0) {
files.add(filename);
multipartStream.readBodyData(new FileOutputStream(outDir + "/" + filename));
}
else {
multipartStream.discardBodyData();
}
}
else {
multipartStream.discardBodyData();
}
nextPart = multipartStream.readBoundary();
}
}
catch(e) {
print(e);
}
}
</bsh>
Uploaded files to <bsh>$$.print(outDir);</bsh>:<br>
<hr>
<bsh>
for(file : files) {
print(file + "<br>");
}
</bsh>
</body>
</html>
Downloads:
paw_fup.zip
Installation:
Unzip into the
/sdcard folder of your Android device.
Access
http:<ip>:8080/ on your device. The File Upload Demo entry should be available in the list of applications.
Attention: There are no access restrictions on the installation directory!
So use this only for a short period of time or password protect the directory by defining a password (PAW Menu -> Server -> Directory Protection).
Uninstall:
Delete the folder /sdcard/paw/html/fup and the file /sdcard/paw/webconf/apps/x01_fup.conf.