簡體   English   中英

使用 Java 在 AWS Lambda 上解析 multipart/form-data Body

[英]Parse multipart/form-data Body on AWS Lambda in Java

我是 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+ 對象來做到這一點,但似乎我無法訪問部件的“名稱”屬性,因此我無法區分相同類型的元素,例如“param1”和“param2”。 我相信這可能與此類用於解析電子郵件的事實有關......是否有另一種方法可以在 lambda 函數中解析這個多部分主體? 這是我必須解析的代碼(base64 是包含正文的字符串):

DataSource source = new ByteArrayDataSource(new ByteArrayInputStream(Base64.decodeBase64(base64)), "multipart/mixed");
MimeMultipart mp = new MimeMultipart(source);

我很感激你能提供的任何幫助。

好的,所以這絕對不是理想的解決方案,但我能夠完成這項工作。

問題

實際上有很多庫可以解析多部分表單數據。 實際問題是所有庫都依賴javax.servlet包 - 最重要的是HttpServletRequest類(以及更多)。

由於我們無法在 AWS Lambda 環境中訪問javax.servlet包類,因此我的解決方案是解決該問題。


解決方案

  1. 從 GitHub下載javax.servlet並將其添加到您的 lambda 函數中。 請參見下圖 - 您可以看到我的類MultipartFormDataTest位於我的包com...並且我在同一個 Java 模塊中也有javax.servlet包。

將 Javax Servlet 包添加到 Lambda 模塊

  1. 一旦我們這樣做了,我們就可以使用一個或多個可以為我們完成所有工作的庫。 我發現可以解析文件內容的最好的庫是 Delight FileUpload - https://mvnrepository.com/artifact/org.javadelight/delight-fileupload

  2. 添加該庫后, 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM