You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java将预签名URL图片存入AWS S3并在Lambda Handler展示?

Got it, let's walk through how to get this done step by step. You'll need to download the Google Static Map image, upload it to S3, then set up a Lambda function to serve it up. Here's a complete solution using Java:

Solution: Store Google Static Map to S3 & Display via AWS Lambda (Java)

Prerequisites

  • An AWS account with an S3 bucket created
  • A Lambda execution role with permissions for s3:PutObject, s3:GetObject, and s3:HeadObject on your bucket
  • Java 11+ (Lambda’s recommended runtime for this use case)
  • AWS SDK for Java 2.x (the latest, most efficient version)

Step 1: Add Dependencies

If using Maven, include these in your pom.xml to pull in the necessary libraries:

<dependencies>
    <!-- AWS SDK for S3 operations -->
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3</artifactId>
        <version>2.25.0</version>
    </dependency>
    <!-- Lambda core library -->
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.2.21</version>
    </dependency>
    <!-- For S3 presigned URLs (if using Option 2) -->
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-presigner</artifactId>
        <version>2.25.0</version>
    </dependency>
</dependencies>

Step 2: Helper to Download the Image from Google

First, let's create a simple method to fetch the image content from your Google Static Map URL:

import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ImageDownloader {
    public static InputStream downloadImage(String imageUrl) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(imageUrl))
                .GET()
                .build();
        
        HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
        
        if (response.statusCode() != 200) {
            throw new RuntimeException("Failed to fetch image: HTTP status " + response.statusCode());
        }
        
        return response.body();
    }
}

Step 3: Helper to Upload the Image to S3

Next, a method to upload the downloaded image stream to your S3 bucket:

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

public class S3Uploader {
    private static final Region REGION = Region.US_EAST_1; // Replace with your bucket's region
    public static final S3Client s3Client = S3Client.builder().region(REGION).build();

    public static void uploadToS3(String bucketName, String objectKey, InputStream imageStream) {
        PutObjectRequest putRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .contentType("image/png") // Google Static Maps return PNG by default
                .build();
        
        s3Client.putObject(putRequest, RequestBody.fromInputStream(imageStream));
    }
}

Step 4: Lambda Handler Implementation

We’ll cover two common ways to display the image: serving it directly from Lambda, or returning a presigned S3 URL for direct access.

Option 1: Serve the Image Directly

This handler checks if the image exists in S3 (to avoid re-downloading every time), then returns the image bytes as a response:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;

import java.util.HashMap;
import java.util.Map;

public class DirectImageHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    private static final String GOOGLE_MAP_URL = "https://maps.googleapis.com/maps/api/staticmap?center=40.7916869275725,-73.9480028393158&size=300x250&zoom=18&maptype=roadmap&key=AIzaSyCJ5YSmLdEUwclkPi2t29IaY0OrDEnjXsw&style=element:geometry|color:0xf5f5f5&style=element:labels.icon|visibility:off&style=element:labels.text.fill|color:0x616161&style=element:labels.text.stroke|color:0xf5f5f5&style=feature:administrative|visibility:off&style=feature:administrative.land_parcel|visibility:off&style=feature:administrative.land_parcel|color:0xbdbdbd&style=feature:poi|visibility:off&style=feature:poi|color:0xeeeeee&style=feature:poi|color:0x757575&style=feature:poi.park|color:0xe5e5e5&style=feature:poi.park|color:0x9e9e9e&style=feature:road|color:0xffffff&style=feature:road|visibility:off&style=feature:road.arterial|color:0x757575&style=feature:road.highway|color:0xdadada&style=feature:road.highway|color:0x616161&style=feature:road.local|visibility:off&style=feature:road.local|color:0x9e9e9e&style=feature:transit|visibility:off&style=feature:transit.line|color:0xe5e5e5&style=feature:transit.station|color:0xeeeeee&style=feature:water|color:0xc9c9c9&style=feature:water|color:0x9e9e9e&path=color:0x000000FF|fillcolor:0x7f97b2|weight:1|40.7917628547078,-73.9474291163126|40.7912643063267,-73.9477918269511|40.7915942270527,-73.9485737283519|40.7920931444449,-73.9482107549615|40.7917628547078,-73.9474291163126";
    private static final String S3_BUCKET = "your-bucket-name"; // Replace with your bucket name
    private static final String S3_OBJECT_KEY = "static-map.png"; // Choose a name for your image

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "image/png");

        try {
            // Check if image already exists in S3
            boolean imageExists = doesObjectExist(S3_BUCKET, S3_OBJECT_KEY);

            if (!imageExists) {
                // Download from Google and upload to S3
                var imageStream = ImageDownloader.downloadImage(GOOGLE_MAP_URL);
                S3Uploader.uploadToS3(S3_BUCKET, S3_OBJECT_KEY, imageStream);
            }

            // Fetch image from S3 and return it
            ResponseBytes<?> imageBytes = S3Uploader.s3Client.getObjectAsBytes(
                    GetObjectRequest.builder().bucket(S3_BUCKET).key(S3_OBJECT_KEY).build());

            response.setStatusCode(200);
            response.setHeaders(headers);
            response.setBody(imageBytes.asBase64());
            response.setIsBase64Encoded(true);

        } catch (Exception e) {
            context.getLogger().log("Error: " + e.getMessage());
            response.setStatusCode(500);
            response.setBody("Failed to load image: " + e.getMessage());
        }

        return response;
    }

    private boolean doesObjectExist(String bucket, String key) {
        try {
            S3Uploader.s3Client.headObject(
                    software.amazon.awssdk.services.s3.model.HeadObjectRequest.builder()
                            .bucket(bucket)
                            .key(key)
                            .build());
            return true;
        } catch (software.amazon.awssdk.services.s3.model.NoSuchKeyException e) {
            return false;
        }
    }
}

Option 2: Return a Presigned S3 URL

If you prefer to let users access the image directly from S3 (more efficient for large images), this handler generates a time-limited presigned URL:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

public class PresignedUrlHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    private static final String GOOGLE_MAP_URL = "https://maps.googleapis.com/maps/api/staticmap?center=40.7916869275725,-73.9480028393158&size=300x250&zoom=18&maptype=roadmap&key=AIzaSyCJ5YSmLdEUwclkPi2t29IaY0OrDEnjXsw&style=element:geometry|color:0xf5f5f5&style=element:labels.icon|visibility:off&style=element:labels.text.fill|color:0x616161&style=element:labels.text.stroke|color:0xf5f5f5&style=feature:administrative|visibility:off&style=feature:administrative.land_parcel|visibility:off&style=feature:administrative.land_parcel|color:0xbdbdbd&style=feature:poi|visibility:off&style=feature:poi|color:0xeeeeee&style=feature:poi|color:0x757575&style=feature:poi.park|color:0xe5e5e5&style=feature:poi.park|color:0x9e9e9e&style=feature:road|color:0xffffff&style=feature:road|visibility:off&style=feature:road.arterial|color:0x757575&style=feature:road.highway|color:0xdadada&style=feature:road.highway|color:0x616161&style=feature:road.local|visibility:off&style=feature:road.local|color:0x9e9e9e&style=feature:transit|visibility:off&style=feature:transit.line|color:0xe5e5e5&style=feature:transit.station|color:0xeeeeee&style=feature:water|color:0xc9c9c9&style=feature:water|color:0x9e9e9e&path=color:0x000000FF|fillcolor:0x7f97b2|weight:1|40.7917628547078,-73.9474291163126|40.7912643063267,-73.9477918269511|40.7915942270527,-73.9485737283519|40.7920931444449,-73.9482107549615|40.7917628547078,-73.9474291163126";
    private static final String S3_BUCKET = "your-bucket-name";
    private static final String S3_OBJECT_KEY = "static-map.png";
    private static final Region REGION = Region.US_EAST_1;

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");

        try {
            // Ensure image is in S3
            boolean imageExists = doesObjectExist(S3_BUCKET, S3_OBJECT_KEY);
            if (!imageExists) {
                var imageStream = ImageDownloader.downloadImage(GOOGLE_MAP_URL);
                S3Uploader.uploadToS3(S3_BUCKET, S3_OBJECT_KEY, imageStream);
            }

            // Generate presigned URL (valid for 1 hour)
            try (S3Presigner presigner = S3Presigner.builder().region(REGION).build()) {
                GetObjectRequest getRequest = GetObjectRequest.builder()
                        .bucket(S3_BUCKET)
                        .key(S3_OBJECT_KEY)
                        .build();

                GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
                        .getObjectRequest(getRequest)
                        .signatureDuration(Duration.ofHours(1))
                        .build();

                String presignedUrl = presigner.presignGetObject(presignRequest).url().toString();
                response.setStatusCode(200);
                response.setHeaders(headers);
                response.setBody("{\"presignedUrl\": \"" + presignedUrl + "\"}");
            }

        } catch (Exception e) {
            context.getLogger().log("Error: " + e.getMessage());
            response.setStatusCode(500);
            response.setBody("{\"error\": \"Failed to generate URL: " + e.getMessage() + "\"}");
        }

        return response;
    }

    private boolean doesObjectExist(String bucket, String key) {
        try {
            S3Client s3Client = S3Client.builder().region(REGION).build();
            s3Client.headObject(software.amazon.awssdk.services.s3.model.HeadObjectRequest.builder()
                    .bucket(bucket)
                    .key(key)
                    .build());
            s3Client.close();
            return true;
        } catch (software.amazon.awssdk.services.s3.model.NoSuchKeyException e) {
            return false;
        }
    }
}

Key Things to Remember

  • IAM Permissions: Attach this policy to your Lambda execution role (replace your-bucket-name):
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": ["s3:PutObject", "s3:GetObject", "s3:HeadObject"],
                "Resource": "arn:aws:s3:::your-bucket-name/*"
            }
        ]
    }
    
  • Google API Key: Make sure your key has the Static Maps API enabled and is restricted to prevent unauthorized use.
  • Caching: The check for existing S3 objects saves you from re-downloading the image every time Lambda runs. For dynamic maps, adjust the object key to match map parameters.
  • Deployment: Package your code into a JAR (including dependencies) and upload it to Lambda, or use AWS SAM for automated deployment.

内容的提问来源于stack exchange,提问作者ShaiNe Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:03:30