簡體   English   中英

帶有 Java AWS Lambda 的 POJO 輸入處理程序的大寫字段

[英]Capitalized fields with POJO Input Handlers for Java AWS Lambda

根據此處描述的文檔: http : //docs.aws.amazon.com/lambda/latest/dg/java-programming-model-req-resp.html可以創建自己的 POJO 來序列化 Java AWS 的輸入和輸出拉姆達。

但是,對於字段大寫的輸入請求,它似乎不能正常工作。 例如,自定義資源 lambda 的輸入格式如下所示:

{"RequestType":"Create", 
"ServiceToken":"arn:aws:lambda:....", 
"ResponseURL":"https://cloudformation-custom-resource-response-e...",
...}

這可以通過這個簡單的 MCVE 代碼輕松測試:

package test;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TestLambda implements RequestHandler<TestLambda.TestEvent, String> {

    private static final Logger logger = LogManager.getLogger(TestLambda.class);

    @Override
    public String handleRequest(TestEvent event, Context context) {
         logger.debug(event.toString());    
         return null;
    }

    public static final class TestEvent {
        private String key1;

        private String Key2;

        private String key3;

        public String getKey1() {
            return key1;
        }

        public void setKey1(String key1) {
            this.key1 = key1;
        }

        public String getKey2() {
            return Key2;
        }

        public void setKey2(String key2) {
            Key2 = key2;
        }

        public String getKey3() {
            return key3;
        }

        public void setKey3(String key3) {
            this.key3 = key3;
        }

        @Override
        public String toString() {
            return "TestEvent{" +
                    "key1='" + key1 + '\'' +
                    ", Key2='" + Key2 + '\'' +
                    ", key3='" + key3 + '\'' +
                    '}';
        }
    }
}

然后在 AWS 控制台中為此 lambda 創建一個測試,並將以下 json 作為請求傳遞到那里:

{
  "key3": "value3",
  "Key2": "value2",
  "Key1": "value1"
}

日志中的結果將是:

2017-11-06 09:30:13 16849696-c2d5-11e7-80c3-150a37863c42 DEBUG TestLambda:15 - TestEvent{key1='null', Key2='null', key3='value3'}

有什么方法可以反序列化這個輸入而不像他們在該主題中建議的那樣處理原始字節流?

您不應該依賴序列化框架的任何其他功能,例如注釋。 如果您需要自定義序列化行為,您可以使用原始字節流來使用您自己的序列化。

如果我們不能為任何類型的事件自由創建 POJO,這在我看來是 Java AWS Lambdas 的一個很大限制。

在 pojo 中,將字段設為公開,並且與 json 字段的大小寫完全相同。 這意味着你應該有大寫的駝峰字段,例如,

public class TestEvent {
    public String Key1;

    public String Key2;

    public String key3;
}

我無法解釋為什么這有效,但我今天根據同事的建議嘗試了這個,並且有效。 我知道它看起來不優雅。 但至少它比反序列化流更少的代碼行。

我在同一個問題上已經很長時間了,終於找到了答案:

Lambda 有一個藍圖: https : //github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/blob/0f7f3d933741a48c08c85feff267793f60b61a60/blueprints/java/src/io/AuthPolicy.java#L

所以基本上你需要做的是覆蓋你的 JSON 的 get 方法。 並在此方法中返回 Map<String, Object> 。 現在您可以在地圖中使用大寫鍵來解決問題:

public Map<String, Object> getPolicyDocument() {
        Map<String, Object> serializablePolicy = new HashMap<>();
        serializablePolicy.put(VERSION, policyDocumentObject.Version);
        Statement[] statements = policyDocumentObject.getStatement();
        Map<String, Object>[] serializableStatementArray = new Map[statements.length];
        for (int i = 0; i < statements.length; i++) {
            Map<String, Object> serializableStatement = new HashMap<>();
            AuthPolicy.Statement statement = statements[i];
            serializableStatement.put(EFFECT, statement.Effect);
            serializableStatement.put(ACTION, statement.Action);
            serializableStatement.put(RESOURCE, statement.getResource());
            serializableStatement.put(CONDITION, statement.getCondition());
            serializableStatementArray[i] = serializableStatement;
        }
        serializablePolicy.put(STATEMENT, serializableStatementArray);
        return serializablePolicy;
    }

Java bean 上的屬性仍然是key2 ,全部小寫,因為序列化框架可見的屬性名稱是從 getter 派生的,而不是私有字段名稱。 所以它仍然進入輸入事件尋找key2而不是Key2

暫無
暫無

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

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