I am new to AWS Lambda and I am trying to implement a Lambda function that receives a POST request containing data encoded as multipart/form-data. The message is received th
Ok so this is definitely NOT the ideal solution but I was able to make this work.
There are actually many libraries out there to parse multipart form data. The actual problem is all libraries rely on javax.servlet
package - most importantly HttpServletRequest
class (and few more).
Since we can't access javax.servlet
package classes in AWS Lambda environment, my solution is to fix that.
javax.servlet
package from GitHub and add that to you your lambda function. See the image below - you can see that my class MultipartFormDataTest
is within my package com...
and I also have javax.servlet
package within the same Java module.Once we do this, we can use one or more libraries that will do all the work for us. The best library I've found that will parse the file content is Delight FileUpload - https://mvnrepository.com/artifact/org.javadelight/delight-fileupload.
Once that library is added, the method below getFilesFromMultipartFormData()
will return ArrayList<File>
where each item in the list represents a File
that was sent in the request.
/**
* @param context context
* @param body this value taken from the `request.getBody()`
* @param contentType this value is taken from `request.headers().get("Content-Type")`
* @return List of File objects
*/
private List<File> getFilesFromMultipartFormData(Context context, String body, String contentType) {
ArrayList<File> files = new ArrayList<>();
List<FileItem> fileItems = FileUpload.parse(body.getBytes(StandardCharsets.UTF_8), contentType);
for(FileItem fileItem : fileItems) {
if(fileItem == null) {
continue;
}
logger.log("fileItem name: " + fileItem.getName());
logger.log("fileItem content-type: " + fileItem.getContentType());
logger.log("fileItem size: " + fileItem.getSize());
// Note: instead of storing it locally, you can also directly store it to S3 for example
try {
// I'm setting the extension to .png but you can look at the fileItem.getContentType()
// to make sure it is an image vs. pdf vs. some other format
File temp = File.createTempFile(fileItem.getName(), ".png");
Files.copy(fileItem.getInputStream(), temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
files.add(temp);
} catch (Exception e) {
continue;
}
}
return files;
}