> Absolutely. Please share. I've been working on this for about 4 days now. I
> also posted my errors with Google App Engine on this group. I will be so
> interested.
Here it is. The solution consists of 4 classes:
=1=================================================================
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.channels.Channels;
import org.apache.commons.fileupload.FileItem;
import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
public class FilesAPIFileItem implements FileItem {
private static final long serialVersionUID = 1;
private String field;
private String type;
private boolean formField;
private String name;
static private FileService fileService =
FileServiceFactory.getFileService();
static private BlobstoreService blobstoreService =
BlobstoreServiceFactory.getBlobstoreService();
private AppEngineFile file = null;
public FilesAPIFileItem(
String fieldName,
String contentType,
boolean isFormField,
String fileName ) throws IOException {
field = fieldName;
type = contentType;
formField = isFormField;
name = fileName;
file = fileService.createNewBlobFile( contentType );
}
@Override
public void delete() {
BlobKey key = getKey();
if( key != null ) {
blobstoreService.delete( key );
file = null;
}
}
@Override
public byte[] get() {
BlobKey key = getKey();
if( key == null )
return null;
return blobstoreService.fetchData( key, 0, getSize() - 1 );
}
@Override
public String getContentType() {
return type;
}
@Override
public String getFieldName() {
return field;
}
@Override
public InputStream getInputStream() throws IOException {
if( file == null )
return null;
FileReadChannel channel = fileService.openReadChannel( file,
false );
return Channels.newInputStream( channel );
}
@Override
public String getName() {
return name;
}
@Override
public OutputStream getOutputStream() throws IOException {
if( file == null )
return null;
return new FilesAPIOutputStream( fileService, file );
}
@Override
public long getSize() {
BlobKey key = getKey();
if( key == null )
return 0;
BlobInfo info = new BlobInfoFactory().loadBlobInfo( key );
if( info == null )
return 0;
return info.getSize();
}
@Override
public String getString() {
return get().toString();
}
@Override
public String getString( String encoding ) throws
UnsupportedEncodingException {
return new String( get(), encoding );
}
@Override
public boolean isFormField() {
return formField;
}
@Override
public boolean isInMemory() {
return false;
}
@Override
public void setFieldName( String arg0 ) {
field = arg0;
}
@Override
public void setFormField( boolean arg0 ) {
formField = arg0;
}
@Override
public void write(File arg0) throws Exception {
throw new UnsupportedOperationException( "Writing to file is
not allowed" );
}
public BlobKey getKey() {
if( file == null )
return null;
return fileService.getBlobKey( file );
}
}
=2===============================================================
import gwtupload.server.MemoryFileItemFactory;
import java.io.IOException;
import org.apache.commons.fileupload.FileItem;
public class FilesAPIFileItemFactory extends MemoryFileItemFactory {
private static final long serialVersionUID = 1;
public FilesAPIFileItemFactory() {
// Consider that there are no fields in the form being posted whose
value can exceed 1024 bytes
super( 1024 );
}
@Override
public FileItem createItem( String fieldName, String contentType,
boolean isFormField, String fileName ) {
if( isFormField )
return super.createItem( fieldName, contentType, isFormField,
fileName );
try {
return new FilesAPIFileItem( fieldName, contentType, isFormField,
fileName );
} catch( IOException x ) {
return null;
}
}
}
=3========================================================================
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.Channels;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileWriteChannel;
public class FilesAPIOutputStream extends OutputStream {
private FileWriteChannel channel;
private OutputStream stream;
public FilesAPIOutputStream( FileService service, AppEngineFile
file ) throws IOException {
channel = service.openWriteChannel( file, true );
stream = Channels.newOutputStream( channel );
}
@Override
public void close() throws IOException {
stream.close();
channel.closeFinally();
}
@Override
public void flush() throws IOException {
stream.flush();
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
stream.write( b, off, len );
}
@Override
public void write(byte[] b) throws IOException {
stream.write( b );
}
@Override
public void write(int b) throws IOException {
stream.write( b );
}
}
=4================================================================
import org.apache.commons.fileupload.FileItemFactory;
import gwtupload.server.UploadAction;
public class FilesAPIUploadAction extends UploadAction {
private static final long serialVersionUID = 1;
@Override
protected FileItemFactory getFileItemFactory( int requestSize ) {
return new FilesAPIFileItemFactory();
}
}
==================================================================
Special servlets handling individual uploads should be derived from
FilesAPIUploadAction.
Note that all this is compatible with GAE version 1.4.3 and probably
with future versions (1.4.3 is the current one).