AWS Open Source Blog

Getting started with Spring Boot on AWS: Part 1

This is a guest post from Björn Wilmsmann, Philip Riecks, and Tom Hombergs, authors of the upcoming bookStratospheric: From Zero to Production with Spring Boot and AWS.

Spring Bootis the leading framework for building applications in theJava Virtual Machine (JVM)ecosystem. In a nutshell, open source Spring Boot adds auto-configuration on top of the Spring framework by following convention over configuration. In this two-part tutorial, we’ll demonstrate how easy it is to get started with Spring Boot andAmazon Web Services (AWS)usingSpring Cloud for AWS.

Introduction to Spring Cloud for AWS

At its core, the Spring framework enables Java developers (or those using any other JVM language, such as Kotlin) to write modern enterprise applications with ease by providing features like an infrastructure as code (IoC) container; an event framework; a Model, View, Controller (MVC) framework; common data access; and many more.

Spring Cloud for AWS is a sub-project of Spring supporting rapid development for cloud-native applications. When it comes to deploying applications, integration with the cloud provider is key. As AWS provides a Java SDK for connecting to services, there is some general bootstrapping involved that you need for each project: instantiating the AWS client with the correct region and credentials. Furthermore, you might not always want to work with the “low-level” API of the AWS clients but prefer integration with your tried-and-true development techniques: auto-configuration with convention over configuration.

Spring Cloud for AWS comes into play as an integrator of AWS services. In this tutorial, we’ll develop a demo application that integrates with the core servicesAmazon Simple Storage Service (Amazon S3)andAmazon Simple Queue Service (Amazon SQS).In part 1, we’ll show how to display content of an S3 bucket with Thymeleaf, and inpart 2,we’ll cover subscribing to an SQS queue and externalizing the configuration of our application using the Parameter Store ofAWS Systems Manager.

Prerequisites

As a prerequisite, you should be familiar with Java and have basic experience with Spring Boot. A general understanding of Amazon S3 and Amazon SQS is a plus.

On the AWS infrastructure side, we need the following: an S3 bucket with publicly accessible content and a notification configuration to send events on each file upload to a SQS queue that our application is subscribed to.

Diagram showing the infrastructure side of the S3 bucket, SQS queue, and Spring Boot application.

You can find the correspondingAWS CloudFormationsetup onGitHub.

Setting up Spring Cloud for AWS

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.cloud:spring-cloud-starter-aws'
implementation 'org.springframework.cloud:spring-cloud-starter-aws-messaging'
implementation 'org.springframework.cloud:spring-cloud-starter-aws-parameter-store-config'
}

The fullbuild.gradlecan be found onGitHub.

First, we need to configure the access to AWS. TheAWS SDK for Javaalready offers several solutions for this, such as, using environment variables, a property file or loading them from theAmazon Elastic Compute Cloud (Amazon EC2)Instance Metadata Service.

Spring Cloud for AWS lets us configure the credentials the “Spring Boot way.” Therefore, we can store the credentials inside ourapplication.ymlby defining bothcloud.aws.credentials.secret-keyandcloud.aws.credentials.access-key:

cloud:
aws:
credentials:
access-key: KEY
secret-key: SECRET

Because we don’t want to store the credentials in plain text inside ourapplication.yml,we can externalize them and pass them via command-line arguments or environment variable. For this demo, we’ll be using a mixed approach and define the AWS profile inside theapplication.ymland store the credentials for this profile inside~/.aws/credentials:

cloud:
aws:
credentials:
profile-name: stratospheric

Content of~/.aws/credentials:

[stratospheric]
aws_access_key_id=KEY
aws_secret_access_key=SECRET

What’s left is to configure the AWS region. Spring Cloud for AWS can automatically detect this based on your environment or stack once you enable the Spring Boot propertycloud.aws.region.auto.

You can also set the region in a static fashion for your application:

cloud:
aws:
region:
static: eu-central-1
auto: false

Feature 1: Displaying content of a S3 Bucket with Thymeleaf

For the first feature of our demo application, we want to display the content of a predefined S3 bucket.

Screenshot showing the Simple S3 File Viewer within Spring Boot.

Spring Cloud for AWS configures theAmazonS3Clientfor us out-of-the-box (using the correct credentials and region). Hence, we can inject it into ourDashboardControllerand start using it:

@Controller
public class DashboardController {

private final String bucketName;
private final AmazonS3Client amazonS3Client;

private String bucketLocation;

public DashboardController(
@Value( "${custom.bucket-name}" ) String bucketName,
AmazonS3Client amazonS3Client) {
this.bucketName = bucketName;
this.amazonS3Client = amazonS3Client;
}

@PostConstruct
public void postConstruct() {
this.bucketLocation = String.format( "https://%s.s3.%s.amazonaws",
bucketName, this.amazonS3Client.getBucketLocation(bucketName));
}

}

Apart from injecting theAmazonS3Client,we look up the property value (custom.bucket-name) of the S3 bucket for which we want to display the content.

Using@PostConstruct,because we want our Java constructor to be free of any side effects, we fetch the location of our bucket. We need thisbucketLocationto construct the download links for the files later on.

For our Thymeleaf view, we are using Spring MVC to expose a controller endpoint that serves our view. As we render this view on the server side, we can pass data as part of the model to our view:

@GetMapping( "/" )
public ModelAndView getDashboardView() {
ModelAndView modelAndView = new ModelAndView( "dashboard" );
modelAndView.addObject( "message", "Spring Boot with AWS" );
modelAndView.addObject( "bucketName", bucketName);
modelAndView.addObject( "bucketLocation", bucketLocation);
modelAndView.addObject( "availableFiles", amazonS3Client.listObjects(bucketName).getObjectSummaries());
return modelAndView;
}

We can then access the model inside the view, to render a HTML table with a row for each file in theS3 bucket:

<div class= "container" >
<h1 style= "text-align: center; margin-top: 10px" th:text= "'Welcome to ' + ${message} + '?'" ></h1>
<h3>Simple S3 File Viewer </h3>
<p>These are the available files inside your S3 Bucket: <strong>[[${bucketName}]]</strong></p>
<table class= "table" >
<thead>
<tr>
<th scope= "col" ><i class= "fas fa-file" ></i></th>
<th scope= "col" >Name</th>
<th scope= "col" >Size</th>
<th scope= "col" >Last modified</th>
<th scope= "col" >Actions</th>
</tr>
</thead>
<tr th:each= "file, iteration: ${availableFiles}" >
<td scope= "row" >[[${iteration.count}]]</td>
<td>[[${file.key}]]</td>
<td>[[${file.size}]] Bytes</td>
<td>[[${#dates.format(file.lastModified, 'd. MMM. yyyy HH:mm:ss Z')}]]</td>
<td>
<a download target= "_blank" th:href= "${bucketLocation} + '/' + ${file.key}" >
<i class= "fas fa-download" ></i> Download
</a>
</td>
</tr>
</table>
</div>

We can now access the Simple S3 File Viewer, after starting our application with./gradlew bootRun,athttp://localhost:8080/.

In part 1 of this tutorial, we provided a brief introduction to Spring Cloud for AWS and began developing a demo application that integrates with core Amazon services. Inpart 2,we’ll continue our demonstration by incorporating additional features, including subscribing to an SQS queue and externalizing the application configuration.

Feature image via Pixabay.

Björn Wilmsmannwidth=” 150″ height=” 150″ />

Björn Wilmsmann

Björn Wilmsmann is an independent IT consultant who helps companies transform their business into a digital business. A longtime software entrepreneur, he’s interested in web apps and SaaS products. He designs and develops business solutions and enterprise applications for his clients. Apart from helping companies in matters of software quality and improving the availability of and access to information through APIs, Björn provides hands-on training in technologies such as Angular and Spring Boot.

Philip Rieckswidth=” 150″ height=” 150″ />

Philip Riecks

Under the sloganTesting Java Applications Made Simple,Philip provides recipes and tips & tricks to accelerate your testing success on both hisblogand onYouTube.He is an independent IT consultant from Berlin and is working with Java, Kotlin, Spring Boot, and AWS on a daily basis.

Tom Hombergswidth=” 150″ height=” 150″ />

Tom Hombergs

Tom is a senior software engineer at Atlassian in Sydney, working with AWS and Spring Boot at scale. He is running the successful software development blogreflectoring.io,regularly writing about Java, Spring, and AWS with the goal of explaining not only the “how” but the “why” of things. Tom is the author ofGet Your Hands Dirty on Clean Architecture,which explores how to implement a hexagonal architecture with Spring Boot.

The content and opinions in this post are those of the third-party author and AWS is not responsible for the content or accuracy of this post.

Ricardo Sueiras

Ricardo Sueiras

Cloud Evangelist at AWS. Enjoy most things where technology, innovation and culture collide into sometimes brilliant outcomes. Passionate about diversity and education and helping to inspire the next generation of builders and inventors with Open Source.