我是 AWS Lambda 新手,我正在尝试实现一个 Lambda 函数,该函数接收包含编码为 multipart/form-data 的数据的 POST 请求。该消息是使用 Lambda 代理集成通过 API 网关接收的,并且正文在到达 Lambda 函数时以 Base64 进行编码。手动解码后,我看到它包含一个多部分主体,如下所示:
-----WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="param1"
value1
-----WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="param2"
value2
------WebKitFormBoundary3EZ0C3tbP2JpAmz4
Content-Disposition: form-data; name="myfile"; filename="ivr.png"
Content-Type: image/png
PNG
... [binary stuff]
------WebKitFormBoundary3EZ0C3tbP2JpAmz4--
我需要的是在 java 8 中解析此消息,以便我可以访问各个部分。我设法使用 +javax.mail.Multipart+ 对象来做到这一点,但似乎我无法访问部件的“名称”属性,因此我无法区分相同类型的元素,例如“参数1”和“参数2”。
我相信这可能与该类用于解析电子邮件的事实有关......
是否有另一种方法可以在 lambda 函数内解析这个多部分主体?这是我必须解析它的代码(base64 是包含主体的字符串):
DataSource source = new ByteArrayDataSource(new ByteArrayInputStream(Base64.decodeBase64(base64)), "multipart/mixed");
MimeMultipart mp = new MimeMultipart(source);
如果您能提供任何帮助,我将不胜感激。
好吧,这绝对不是ideal解决方案,但我能够完成这项工作。
Problem
实际上有很多库可以解析多部分表单数据。实际问题是所有库都依赖javax.servlet
包——最重要的是HttpServletRequest
类(还有更多)。
由于我们无法访问javax.servlet
在AWS Lambda环境中打包类,我的解决方案是解决这个问题。
Solution
- 下载
javax.servlet
来自 GitHub 的包并将其添加到您的 lambda 函数中。请看下图 - 你可以看到我的班级MultipartFormDataTest
在我的包裹内com...
我也有javax.servlet
包在同一个 Java 模块中。
-
一旦我们这样做了,我们就可以使用一个或多个库来为我们完成所有工作。我发现可以解析文件内容的最好的库是 Delight FileUpload -https://mvnrepository.com/artifact/org.javadelight/delight-fileupload.
-
添加该库后,可以使用以下方法getFilesFromMultipartFormData()
将返回ArrayList<File>
其中列表中的每个项目代表一个File
这是在请求中发送的。
/**
* @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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)