Search code examples
javaamazon-s3jasper-reports

how to display amazon S3 image in jasper reports


i can display image to pdf when i use local image path with jasper-reports, but i need to get the image from amazon S3, how can i display amazon S3 image to pdf by java? should i download the image from amazonS3 first? or link the full image path in jasper report? for example, i linked the local image path by jasper-reports, if i want to get the image from amazonS3 , how can i do that? please hlpe me.

<imageExpression class="java.lang.String"><![CDATA["image_name.jpg"]]></imageExpression>

Solution

  • You can generate a pre-signed URL of the S3 image object using AWS Java SDK and use the pre-signed URL in the jasper-reports. In this way, you don't have to download the image from S3. Please note that there is an expiry time for the pre-signed which can be set from java.

    Below is the code snippet for reference to generate S3 pre-signed URL.

    More details in this link. https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html

    public class GenerateS3SignedUrl implements BiFunction<String, String, String> {
        @Override
        @SneakyThrows
        public String apply(String bucketName, String objectKey) {
            String awsRegion = StringUtils.isEmpty(System.getenv(Constant.REGION)) ? Constant.DEFAULT_REGION :
                    System.getenv(Constant.REGION);
    
            log.info("calculating expiration hrs defaults to 2 hrs");
            int expirationHrs;
            if (StringUtils.isEmpty(System.getenv(Constant.EXPIRATION_DURATION))) {
                expirationHrs = 2;
            } else if (!StringUtils.isNumeric(System.getenv(Constant.EXPIRATION_DURATION))) {
                expirationHrs = 2;
            } else {
                expirationHrs = Integer.parseInt(System.getenv(Constant.EXPIRATION_DURATION));
            }
    
            long expirationInMillis = 1000L * 60 * 60 * expirationHrs;
            log.info("create pre-signed url generate request..");
            GeneratePresignedUrlRequest generatePresignedUrlRequest =
                    new GeneratePresignedUrlRequest(bucketName, objectKey)
                            .withMethod(HttpMethod.GET)
                            .withExpiration(Date.from(Instant.now().plusMillis(expirationInMillis)));
    
            log.info("generate pre-signed url..");
            URL preSignedUrl = AwsCommonConfig.getAmazonS3Client(awsRegion)
                    .generatePresignedUrl(generatePresignedUrlRequest);
    
            log.info("return pre-signed url for file : {} with expiration in {} hrs.", objectKey, expirationHrs);
            return preSignedUrl.toString();
        }
    }    
    public class AwsCommonConfig {
        private static AmazonS3 amazonS3;
    
        public static AmazonS3 getAmazonS3Client (String awsRegion) {
            if (amazonS3 == null) {
                amazonS3 = AmazonS3ClientBuilder.standard()
                        .withRegion(awsRegion)
                        .withPathStyleAccessEnabled(true)
                        .build();
            }
            return amazonS3;
        }
    
    }