AWS Lambda 有提供 proxy framework 掛上 jersey。 首先加上依賴包,
// build.gradle dependencies { compile ( 'com.amazonaws.serverless:aws-serverless-java-container-jersey:1.1.3', 'org.glassfish.jersey.media:jersey-media-json-jackson:2.27', 'org.glassfish.jersey.inject:jersey-hk2:2.27' ) }
然後接口要換掉 (RequestHandler -> RequestStreamHandler),
package example; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler; import com.amazonaws.serverless.proxy.model.AwsProxyRequest; import com.amazonaws.serverless.proxy.model.AwsProxyResponse; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; public final class ProxyWithStream implements RequestStreamHandler { private static final ResourceConfig jerseyApplication = new ResourceConfig() .packages("<PACKAGE-NAME>") .register(JacksonFeature.class); private static final JerseyLambdaContainerHandler其中handler = JerseyLambdaContainerHandler .getAwsProxyHandler(jerseyApplication); @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { handler.stripBasePath("<API-GATEWAY-PATH>"); handler.proxyStream(inputStream, outputStream, context); outputStream.close(); } }
<PACKAGE-NAME>
要輸入 resource 路徑,
<API-GATEWAY-PATH>
則是端視在 API Gateway 的設定。
假設 API Gateway 設定 "/v1/foo/{proxy+}", JAX-RS 設定 APIs 為 "/bar/{id}",
<API-GATEWAY-PATH>
就要設定為 "/v1/foo"。
接下來 Lambda 測試的 payload 需要更改成 API Gateway 傳給 Lambda 的格式,然後就可以測試了。
{ "body": "", // POST/PUT/PATCH body 的來源 "resource": "/{proxy+}", "requestContext": { "resourceId": "123456", "apiId": "1234567890", "resourcePath": "/{proxy+}", "httpMethod": "GET", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "identity": { "apiKey": null, "userArn": null, "cognitoAuthenticationType": null, "caller": null, "userAgent": "Custom User Agent String", "user": null, "cognitoIdentityPoolId": null, "cognitoIdentityId": null, "cognitoAuthenticationProvider": null, "sourceIp": "127.0.0.1", "accountId": null }, "stage": "prod" }, "queryStringParameters": { "fields": "name" // query parameters 的來源 }, "headers": { "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", "Accept-Language": "en-US,en;q=0.8", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "User-Agent": "Custom User Agent String", "Accept-Encoding": "gzip, deflate, sdch" }, "pathParameters": { "proxy": "bar/12345" }, "httpMethod": "GET", // method 的來源 "stageVariables": {}, "path": "/v1/foo/bar/12345" // url mapping 的來源 }
參考資料:
- GitHub: awslabs/aws-serverless-java-container
- StackOverflow: Jersey stopped working with InjectionManagerFactory not found
- GitHub: awslabs/aws-serverless-java-container - Issue#130: Pet store sample throw
- GitHub: awslabs/aws-serverless-java-container - Issue#112: API Gateway Path Mapping Problem
系列:
- [Java] AWS Lambda 入門
- [Java] AWS Lambda + DynamoDB
- AWS Lambda + API Gateway
- [Java] JAX-RS on AWS Lambda
- [Java] JUnit with DynamoDBLocal
Thank you for your information.it is very nice article.
回覆刪除AWS Online Training