【问题标题】:Get Mapping Template from API Gateway as JSON in AWS Lambda Java Project在 AWS Lambda Java 项目中从 API Gateway 获取作为 JSON 的映射模板
【发布时间】:2017-09-27 23:15:40
【问题描述】:

我设置了一个 API Gateway GET 方法,该方法与基本的 AWS Lambda 函数集成。我已经在集成请求上启用了请求正文直通到预设的方法请求直通模板。

我想根据请求的资源路径做不同的事情。例如,如果路径是 /foo,我将解释 foo 请求,或者 /bar 将解释为 bar 请求,使用相同的 Lambda 函数。所以我需要根据 Lambda 函数本身的资源路径进行切换。

我无法访问映射的有效负载模板。根据AWS help,所有数据都应该在那里。但在 java 中,我不知道如何使用 Jackson、org.json 或 json-path 将 API 网关的输入转换为可解析的 json。

这是我的 Lambda 代码。任何有关如何从 API Gateway GET 获取“资源路径”或任何方法请求传递的帮助将不胜感激。

import org.json.JSONObject;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class LambdaFunctionHandler implements RequestHandler<Object, Object> {

@Override
public Object handleRequest(Object input, Context context) {
    JSONObject inputJson = new JSONObject(input.toString());
    JSONObject contextJson = inputJson.getJSONObject("context");

    String resourcePath = contextJson.getString("resource-path");

    return resourcePath;
}

}

这是我认为作为输入发送到函数中的内容:

{
  "body-json" : {},
  "params" : {
    "path" : {},
    "querystring" : {},
    "header" : {}
  },
  "stage-variables" : {},
  "context" : {
    "account-id" : "xxxxxxxxx",
    "api-id" : "xxxxxxxxx",
    "api-key" : "xxxxxxxxx",
    "authorizer-principal-id" : "",
    "caller" : "xxxxxxxxx",
    "cognito-authentication-provider" : "",
    "cognito-authentication-type" : "",
    "cognito-identity-id" : "",
    "cognito-identity-pool-id" : "",
    "http-method" : "GET",
    "stage" : "test-invoke-stage",
    "source-ip" : "test-invoke-source-ip",
    "user" : "xxxxxxxxxxxxxxxx",
    "user-agent" : "Apache-HttpClient/4.5.x (Java/1.8.0_112)",
    "user-arn" : "arn:aws:iam::230537478972:root",
    "request-id" : "test-invoke-request",
    "resource-id" : "75bakm",
    "resource-path" : "/text"
  }
}

但我得到了:

{
"errorMessage": "Expected a ':' after a key at 11 [character 12 line 1]",
"errorType": "org.json.JSONException",
"stackTrace": [
"org.json.JSONTokener.syntaxError(JSONTokener.java:433)",
"org.json.JSONObject.<init>(JSONObject.java:216)",
"org.json.JSONObject.<init>(JSONObject.java:323)",
"xxx.LambdaFunctionHandler.handleRequest(LambdaFunctionHandler.java:12)"
  ]
}

【问题讨论】:

    标签: java json amazon-web-services lambda aws-api-gateway


    【解决方案1】:

    感谢Ka Hou leong的指导,我已经解决了以下问题:

    1) 在 Maven 中为 aws-serverless-java-container 添加了依赖项

    <dependency>
        <groupId>com.amazonaws.serverless</groupId>
        <artifactId>aws-serverless-java-container-core</artifactId>
        <version>0.4</version>
    </dependency>
    

    2) 修改了我的 LambdaFunctionHandler 类以使用 AwsProxyRequest 和 AwsProxyResponse:

    import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
    import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    
    public class LambdaFunctionHandler implements RequestHandler<AwsProxyRequest, Object> {
    
        public Object handleRequest(AwsProxyRequest input, Context context) {
            AwsProxyResponse response = new AwsProxyResponse();
            String resourcePath = input.getRequestContext().getResourcePath();
    
            response.setStatusCode(200);
            response.setBody(resourcePath);
        return response;
        }
    }
    

    3) 将我的 API Gateway 方法集成请求设置修改为使用 Lambda 代理集成。

    从这里我可以作为 AwsProxyRequest 访问 input 对象中的所有内容,并将 response 作为 AwsProxyResponse 处理我想要响应的任何内容。

    【讨论】:

      【解决方案2】:

      您可以编写自己的 POJO 来匹配来自 API Gateway 的请求,然后您将能够从 getter 访问资源路径。

      POJO 示例:

      public class LambdaFunctionHandler implements RequestHandler<Object, Object> {
      
          @Override
          public Object handleRequest(AwsProxyRequest input, Context context) {
              String resourcePath = input.getRequestContext().getResourcePath();
      
              return resourcePath;
          }
      
      }
      
      public class AwsProxyRequest {
      
          //-------------------------------------------------------------
          // Variables - Private
          //-------------------------------------------------------------
          private ApiGatewayRequestContext requestContext;
          ....
      
          //-------------------------------------------------------------
          // Methods - Getter/Setter
          //-------------------------------------------------------------
      
          public ApiGatewayRequestContext getRequestContext() {
              return requestContext;
          }
      
      
          public void setRequestContext(ApiGatewayRequestContext requestContext) {
              this.requestContext = requestContext;
          }
      
          ....
      
      }
      
      public class ApiGatewayRequestContext {
      
          //-------------------------------------------------------------
          // Variables - Private
          //-------------------------------------------------------------
      
          private String resourcePath;
          ...
      
          //-------------------------------------------------------------
          // Methods - Getter/Setter
          //-------------------------------------------------------------
      
          public String getResourcePath() {
              return resourcePath;
          }
      
      
          public void setResourcePath(String resourcePath) {
              this.resourcePath = resourcePath;
          }
      
          ....
      }
      

      如果你想要完整的代理请求 POJO,你可以从here找到它们。

      【讨论】:

      • 是的!这与一些小的调整一起工作。回答我自己的问题来解释。
      • 在下面查看我的答案。我必须在 maven 中添加依赖项,更改 input 的类型,然后重新配置我的 API 网关以使用 lambda 代理集成。
      • 感谢您指向 aws-serverless-java-container,这就是我要找的东西!
      猜你喜欢
      • 2020-09-28
      • 2017-12-29
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 2018-02-03
      • 1970-01-01
      相关资源
      最近更新 更多