aws / aws/aws-lambda-java-libs

Lambda configure with SAM to read JSON from request body does not work

未关闭
#100 1 条评论 3 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Java
星标
548
派生
241
平均合并
2 天 5 分钟
30 天内合并 PR
11

描述

### Description

Lambda configure with SAM to read JSON from request body does not work

Briefly describe the bug you are facing.

### Steps to reproduce

I tried to develop a simple API where the request is in the form of simple JSON

"{\"test\": \"hello world\"}"

I wrote a sam template as follows

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app

Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 20

Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java8
MemorySize: 512
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /{proxy+}
Method: POST
RestApiId: !Ref HelloWorldApi
RequestModel:
Model: RequestClass # REQUIRED; must match the name of a model defined in the Models property of the AWS::Serverless::API
Required: true # OPTIONAL; boolean

HelloWorldApi:
Name: HelloWorldFunctionApiGateway
Type: AWS::Serverless::Api
Properties:
StageName : dev
Models:
RequestClass :
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "RequestClass",
"type": "object",
"properties": {
"test": { "type": "string" }} }

Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn

```

then I used the event.json as

```sam local invoke HelloWorldFunction --event events/event.json```

```
{
"body": "{\"test\": \"hello world\"}",
"resource": "/{proxy+}",
"path": "/hello",
"httpMethod": "post",
"isBase64Encoded": false,
"queryStringParameters": {
"foo": "bar"
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-east-1.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/prod/path/to/resource",
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
```
Handler is as follows

```

package helloworld;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

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

/**
* Handler for requests to Lambda function.
*/
public class App implements RequestHandler {

public Object handleRequest(RequestClass input, Context context) {

Map headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Custom-Header", "application/json");
**Output of the follwoing line always null**
System.out.println(input.getTest());
try {
final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
String output = String.format(input.toString(), pageContents);
return new GatewayResponse(output, headers, 200);
} catch (IOException e) {
return new GatewayResponse("{}", headers, 500);
}
}

private String getPageContents(String address) throws IOException{
URL url = new URL(address);
try(BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {
return br.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
}

```

Request class is follows

```
package helloworld;

public class RequestClass {
public String test;

public String getTest() {
return test;
}

public void setTest(String test) {
this.test = test;
}

@Override
public String toString() {
return "HelloWorld{" +
"test='" + test + '\'' +
'}';
}

public RequestClass() {
}
}
```

### Observed result

The value of system out should be "Test" but its printing "null" meaning the RequestClass is not mapped with the incoming JSON.
This is supported in AWS lambda as follows
https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-pojo.html

Please provide command output with `--debug` flag set.

### Expected result

Should be able to map JSON to the java POJO object

Describe what you expected.

### Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

1. OS:MAC OS
2. `sam --version`:SAM CLI, version 0.22.0

`Add --debug flag to command you are running`

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。