Last active
December 18, 2015 23:09
-
-
Save Zenithar/5859461 to your computer and use it in GitHub Desktop.
RestExpress MultiPart File Upload support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zenithar.restexpress.config; | |
import com.strategicgains.restexpress.Format; | |
import com.strategicgains.restexpress.RestExpress; | |
import com.strategicgains.restexpress.util.Environment; | |
import org.apache.commons.fileupload.FileUpload; | |
import org.apache.commons.fileupload.disk.DiskFileItemFactory; | |
import org.apache.commons.io.FileCleaningTracker; | |
import java.io.File; | |
import java.util.Properties; | |
/** | |
* @author Thibault NORMAND | |
* @date 25/06/13 | |
*/ | |
public class Configuration | |
extends Environment { | |
private FileUpload fileUpload = new FileUpload(); | |
private DeleteFilesOnEndUploadCleaningTracker fileCleaningTracker = new DeleteFilesOnEndUploadCleaningTracker(); | |
@Override | |
protected void fillValues(Properties p) { | |
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); | |
diskFileItemFactory.setRepository(new File("./tmp")); | |
diskFileItemFactory.setFileCleaningTracker(fileCleaningTracker); | |
this.fileUpload.setFileItemFactory(diskFileItemFactory); | |
} | |
public FileUpload getFileUpload() { | |
return fileUpload; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zenithar.restexpress.utils; | |
import org.apache.commons.io.FileCleaningTracker; | |
import org.apache.commons.io.FileDeleteStrategy; | |
import java.io.File; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class DeleteFilesOnEndUploadCleaningTracker extends FileCleaningTracker { | |
private List<String> filesToDelete = new ArrayList(); | |
public void deleteTemporaryFiles() { | |
for (String file : filesToDelete) { | |
new File(file).delete(); | |
} | |
filesToDelete.clear(); | |
} | |
@Override | |
public synchronized void exitWhenFinished() { | |
deleteTemporaryFiles(); | |
} | |
@Override | |
public int getTrackCount() { | |
return filesToDelete.size(); | |
} | |
@Override | |
public void track(File file, Object marker) { | |
filesToDelete.add(file.getAbsolutePath()); | |
} | |
@Override | |
public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) { | |
filesToDelete.add(file.getAbsolutePath()); | |
} | |
@Override | |
public void track(String path, Object marker) { | |
filesToDelete.add(path); | |
} | |
@Override | |
public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) { | |
filesToDelete.add(path); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zenithar.restexpress.controller; | |
import org.zenithar.restexpress.utils.RestUploadContext; | |
import com.strategicgains.restexpress.Request; | |
import com.strategicgains.restexpress.Response; | |
import org.apache.commons.fileupload.FileItem; | |
import org.apache.commons.fileupload.FileUpload; | |
import org.apache.commons.fileupload.FileUploadException; | |
/** | |
* @author Thibault NORMAND | |
* @date 25/06/13 | |
*/ | |
public class DeliveryController { | |
private FileUpload fileUpload; | |
private DeleteFilesOnEndUploadCleaningTracker tracker; | |
public DeliveryController(FileUpload fileUpload, DeleteFilesOnEndUploadCleaningTracker tracker) { | |
super(); | |
this.fileUpload = fileUpload; | |
this.tracker = tracker; | |
} | |
public void create(Request request, Response response) { | |
RestUploadContext context = RestUploadContext.fromRequest(request); | |
try { | |
List<FileItem> items = fileUpload.parseRequest(context); | |
Map<String , List<FileItem>> parts = MultiPartDecoder.getParts(items); | |
for(FileItem file : parts.get("files")) { | |
// File operation | |
} | |
catch (FileUploadException e) { | |
// Handle errors | |
} finally { | |
tracker.deleteTemporaryFiles(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zenithar.restexpress.utils; | |
import org.apache.commons.fileupload.FileItem; | |
import java.util.LinkedHashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
/** | |
* @author t_no | |
* @date 25/06/13 | |
*/ | |
public final class MultiPartDecoder { | |
private MultiPartDecoder() { | |
throw new AssertionError(); | |
} | |
public static Map<String, List<FileItem>> getParts(List<FileItem> request) { | |
Map<String, List<FileItem>> parts = new LinkedHashMap<String, List<FileItem>>(); | |
for(FileItem it : request) { | |
final String partName = it.getFieldName(); | |
if(parts.containsKey(partName)) { | |
parts.get(partName).add(it); | |
} else { | |
List<FileItem> items = new LinkedList<FileItem>(); | |
items.add(it); | |
parts.put(partName, items); | |
} | |
} | |
return parts; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zenithar.restexpress.utils; | |
import com.strategicgains.restexpress.Request; | |
import org.apache.commons.fileupload.UploadContext; | |
import org.jboss.netty.buffer.ChannelBuffer; | |
import org.jboss.netty.buffer.ChannelBufferInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
/** | |
* @author Thibault NORMAND | |
* @date 25/06/13 | |
*/ | |
public class RestUploadContext implements UploadContext { | |
private final long contentLength; | |
private final String characterEncoding; | |
private final String contentType; | |
private final InputStream inputStream; | |
private RestUploadContext(long contentLength, String characterEncoding, String contentType, InputStream inputStream) { | |
this.contentLength = contentLength; | |
this.characterEncoding = characterEncoding; | |
this.contentType = contentType; | |
this.inputStream = inputStream; | |
} | |
public static RestUploadContext fromRequest(Request request) { | |
return new Builder() | |
.withChannelBuffer(request.getBody()) | |
.withContentType(request.getHeader("Content-Type")) | |
.withContentLength(Long.valueOf(request.getHeader("Content-length"))) | |
.build(); | |
} | |
public static class Builder { | |
private Long contentLength = 0L; | |
private String characterEncoding = "UTF-8"; | |
private String contentType = "multipart/form-data"; | |
private InputStream inputStream; | |
public Builder() { | |
} | |
public Builder withContentLength(long length) { | |
this.contentLength = length; | |
return this; | |
} | |
public Builder withCharacterEncoding(String encoding) { | |
this.characterEncoding = encoding; | |
return this; | |
} | |
public Builder withContentType(String contentType) { | |
this.contentType = contentType; | |
return this; | |
} | |
public Builder withChannelBuffer(ChannelBuffer channel) { | |
this.inputStream = new ChannelBufferInputStream(channel); | |
return this; | |
} | |
public RestUploadContext build() { | |
return new RestUploadContext(contentLength, characterEncoding, contentType, inputStream); | |
} | |
} | |
@Override | |
public long contentLength() { | |
return this.contentLength; | |
} | |
@Override | |
public String getCharacterEncoding() { | |
return this.characterEncoding; | |
} | |
@Override | |
public String getContentType() { | |
return this.contentType; | |
} | |
@Override | |
public int getContentLength() { | |
return Long.valueOf(this.contentLength).intValue(); | |
} | |
@Override | |
public InputStream getInputStream() throws IOException { | |
return inputStream; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you write a sample for upload images?