Skip to content

Add the download functionality to the Spring BOOT Photo example #1933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
703ed23
Create Readme.md
scmacdon Jun 28, 2021
93ebd23
Create CreateCluster.java
scmacdon Jun 28, 2021
16d34d3
Add files via upload
scmacdon Jun 28, 2021
f8a65e2
Update Readme.md
scmacdon Jun 28, 2021
48bf1f7
Create EcsTest.java
scmacdon Jun 28, 2021
355805b
Create config.properties
scmacdon Jun 28, 2021
ace73c1
Update Readme.md
scmacdon Jun 28, 2021
f26c006
Add files via upload
scmacdon Jun 28, 2021
b717371
Add files via upload
scmacdon Jun 28, 2021
8de04ca
Add files via upload
scmacdon Jun 28, 2021
80ccb81
Update ArchiveDownload.java
scmacdon Jun 29, 2021
6130704
Update DescribeInstanceTags.java
scmacdon Jun 29, 2021
362c565
Update Readme.md
scmacdon Jul 19, 2021
21bcfe0
Update Readme.md
scmacdon Jul 19, 2021
48068bd
Update Readme.md
scmacdon Jul 19, 2021
f0ca736
Update Readme.md
scmacdon Jul 19, 2021
9e4da77
Update ArchiveDownload.java
scmacdon Jul 19, 2021
55c1555
Merge branch 'master' into master
irenepsmith Jul 19, 2021
8c36ff4
Update Readme.md
scmacdon Jul 21, 2021
3fbac8e
Add files via upload
scmacdon Jul 21, 2021
8d2712f
Update Readme.md
scmacdon Jul 21, 2021
f29a7c2
Update PhotoController.java
scmacdon Jul 21, 2021
aff2e90
Update AnalyzePhotos.java
scmacdon Jul 21, 2021
f9fe39c
Update BucketItem.java
scmacdon Jul 21, 2021
e643fcb
Update PhotoApplication.java
scmacdon Jul 21, 2021
d8f96f8
Update S3Service.java
scmacdon Jul 21, 2021
8c002e2
Update SendMessages.java
scmacdon Jul 21, 2021
d58a1da
Update WorkItem.java
scmacdon Jul 21, 2021
d0d0abd
Update WriteExcel.java
scmacdon Jul 21, 2021
2a83821
Update Readme.md
scmacdon Jul 21, 2021
a163e88
Update process.html
scmacdon Jul 21, 2021
f037824
Update message.js
scmacdon Jul 21, 2021
b42fa25
Update Readme.md
scmacdon Jul 22, 2021
24993be
Update Readme.md
scmacdon Jul 22, 2021
4cdbfbf
Update S3Service.java
scmacdon Jul 22, 2021
dc4911e
Update PhotoController.java
scmacdon Jul 22, 2021
97cebed
Update Readme.md
scmacdon Jul 22, 2021
cc83dc2
Update PhotoController.java
scmacdon Jul 22, 2021
9b84e88
Update Readme.md
scmacdon Jul 22, 2021
6b2bd1d
Update EcsTest.java
scmacdon Jul 22, 2021
b4f2dd7
Delete EcsTest.java
scmacdon Jul 22, 2021
28b7971
Merge branch 'master' into master
irenepsmith Jul 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 105 additions & 49 deletions javav2/usecases/creating_photo_analyzer_app/Readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Creating an example AWS photo analyzer application using the AWS SDK for Java

## Purpose
You can create an AWS application that analyzes nature images located in an Amazon Simple Storage Service (Amazon S3) bucket by using the Amazon Rekognition service.

The application can analyze many images and generate a report that breaks down each image into a series of labels.
Expand All @@ -26,10 +27,6 @@ This application uses the following AWS services:
* Amazon SES
* AWS Elastic Beanstalk

**Cost to complete:** The AWS services included in this document are included in the [AWS Free Tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc).

**Note:** Be sure to terminate all of the resources you create while going through this tutorial to ensure that you’re no longer charged for them.

#### Topics

+ Prerequisites
Expand All @@ -50,7 +47,17 @@ To complete the tutorial, you need the following:
+ A Java IDE (this tutorial uses the IntelliJ IDE)
+ Java JDK 1.8
+ Maven 3.6 or later
+ An Amazon S3 bucket named **photos[somevalue]**. Be sure to use this bucket name in your Amazon S3 Java code. For information, see [Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html).

### Important

+ The AWS services included in this document are included in the [AWS Free Tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc).
+ This code has not been tested in all AWS Regions. Some AWS services are available only in specific regions. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).
+ Running this code might result in charges to your AWS account.
+ Be sure to terminate all of the resources you create while going through this tutorial to ensure that you’re not charged.

### Creating the resources

Create an Amazon S3 bucket named **photos[somevalue]**. Be sure to use this bucket name in your Amazon S3 Java code. For information, see [Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html).

## Understand the AWS Photo Analyzer application

Expand All @@ -62,6 +69,10 @@ To generate a report, enter an email address and choose **Analyze Photos**.

![AWS Photo Analyzer](images/photo2.png)

You can also download a given image from the Amazon S3 bucket by using this application. Simply specify the image name and choose the **Download Photo** button. The image is downloaded to your browser, as shown in this illustration.

![AWS Photo Analyzer](images/download.png)

## Create an IntelliJ project named SpringPhotoAnalyzer

1. In the IntelliJ IDE, choose **File**, **New**, **Project**.
Expand Down Expand Up @@ -359,6 +370,8 @@ The following Java code represents the **PhotoApplication** class.

The following Java code represents the **PhotoController** class that handles HTTP requests. For example, when a new image is posted (uploaded to an S3 bucket), the **singleFileUpload** method handles the request.

**Note**: Be sure that you change the **bucketName** variable to your Amazon S3 bucket name.

package com.example.photo;

import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -369,13 +382,17 @@ The following Java code represents the **PhotoController** class that handles HT
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.RedirectView;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Controller
public class PhotoController {

// Change to your Bucket Name!
private String bucketName = "<YOUR BUCKET>";

@Autowired
S3Service s3Client;

Expand Down Expand Up @@ -407,69 +424,92 @@ The following Java code represents the **PhotoController** class that handles HT
@ResponseBody
String getImages(HttpServletRequest request, HttpServletResponse response) {

return s3Client.ListAllObjects("scottphoto");
return s3Client.ListAllObjects(bucketName);
}

// Generate a report that analyzes photos in a given bucket
// Generates a report that analyzes photos in a given bucket.
@RequestMapping(value = "/report", method = RequestMethod.POST)
@ResponseBody
String report(HttpServletRequest request, HttpServletResponse response) {

String email = request.getParameter("email");

// Get a list of key names in the given bucket
List myKeys = s3Client.ListBucketObjects("scottphoto");
// Get a list of key names in the given bucket.
List myKeys = s3Client.ListBucketObjects(bucketName);

// Create a list to store the data
List myList = new ArrayList<List>();
// Create a List to store the data.
List<List> myList = new ArrayList<List>();

// Loop through each element in the List
// loop through each element in the List.
int len = myKeys.size();
for (int z=0 ; z < len; z++) {

String key = (String) myKeys.get(z);
byte[] keyData = s3Client.getObjectBytes ("scottphoto", key);
//myMap.put(key, keyData);
byte[] keyData = s3Client.getObjectBytes (bucketName, key);

// Analyze the photo
//Analyze the photo.
ArrayList item = photos.DetectLabels(keyData, key);
myList.add(item);
}

// Now we have a list of WorkItems that have all of the analytical data describing the photos in the S3 bucket
// Now we have a list of WorkItems that have all of the analytical data describing the photos in the S3 bucket.
InputStream excelData = excel.exportExcel(myList);

try {
// Email the report
// Email the report.
sendMessage.sendReport(excelData, email);

} catch (Exception e) {

e.printStackTrace();
}
return "The photos have been analyzed and the report is sent.";
return "The photos have been analyzed and the report is sent";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a period at the end of the sentence.

}

// Upload an image to send to an S3 bucket
// Upload a video to analyze.
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public ModelAndView singleFileUpload(@RequestParam("file") MultipartFile file) {

try {

// Now you can add this to an S3 bucket
byte[] bytes = file.getBytes();
String name = file.getOriginalFilename() ;

// Put the file into the bucket
s3Client.putObject(bytes, "scottphoto", name);
// Put the file into the bucket.
s3Client.putObject(bytes, bucketName, name);

} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView(new RedirectView("photo"));
}


// This controller method downloads the given image from the Amazon S3 bucket.
@RequestMapping(value = "/downloadphoto", method = RequestMethod.GET)
void buildDynamicReportDownload(HttpServletRequest request, HttpServletResponse response) {
try {

// Get the form id from the submitted form.
String photoKey = request.getParameter("photoKey");
byte[] photoBytes = s3Client.getObjectBytes(bucketName, photoKey) ;
InputStream is = new ByteArrayInputStream(photoBytes);

// Define the required information here.
response.setContentType("image/png");
response.setHeader("Content-disposition", "attachment; filename="+photoKey);
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();

} catch (Exception e) {
e.printStackTrace();
}
}
}
}




### S3Service class

Expand Down Expand Up @@ -505,30 +545,30 @@ The following class uses the Amazon S3 API to perform S3 operations. For example

S3Client s3 ;

// Create the S3Client object.
private S3Client getClient() {
// Create the S3Client object

Region region = Region.US_WEST_2;
S3Client s3 = S3Client.builder()
.credentialsProvider(EnvironmentVariableCredentialsProvider.create())
.region(region)
.build();

return s3;
}
}

// Get the byte[] from this AWS S3 object.
public byte[] getObjectBytes (String bucketName, String keyName) {

s3 = getClient();

try {
// Create a GetObjectRequest instance
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(keyName)
.bucket(bucketName)
.build();

// Get the byte[] from this S3 object

ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
byte[] data = objectBytes.asByteArray();
return data;
Expand All @@ -538,9 +578,9 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
System.exit(1);
}
return null;
}
}

// Return the names of all images and data within an XML document
// Returns the names of all images and data within an XML document.
public String ListAllObjects(String bucketName) {

s3 = getClient();
Expand Down Expand Up @@ -579,9 +619,9 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
System.exit(1);
}
return null ;
}
}

// Return the names of all images in the given bucket
// Returns the names of all images in the given bucket.
public List ListBucketObjects(String bucketName) {

s3 = getClient();
Expand All @@ -604,7 +644,7 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
keys.add(keyName);
}

return keys;
return keys;

} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
Expand All @@ -614,13 +654,12 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
}


// Place an image into an S3 bucket
// Places an image into a S3 bucket.
public String putObject(byte[] data, String bucketName, String objectKey) {

s3 = getClient();

try {
// Put a file into the bucket
PutObjectResponse response = s3.putObject(PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
Expand All @@ -634,59 +673,59 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
System.exit(1);
}
return "";
}
}

// Convert bucket item data into XML to pass back to the view
// Convert items into XML to pass back to the view.
private Document toXml(List<BucketItem> itemList) {

try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();

// Start building the XML
// Start building the XML.
Element root = doc.createElement( "Items" );
doc.appendChild( root );

// Get the elements from the collection
// Get the elements from the collection.
int custCount = itemList.size();

// Iterate through the collection
// Iterate through the collection.
for ( int index=0; index < custCount; index++) {

// Get the WorkItem object from the collection
// Get the WorkItem object from the collection.
BucketItem myItem = itemList.get(index);

Element item = doc.createElement( "Item" );
root.appendChild( item );

// Set Key
// Set Key.
Element id = doc.createElement( "Key" );
id.appendChild( doc.createTextNode(myItem.getKey()) );
item.appendChild( id );

// Set Owner
// Set Owner.
Element name = doc.createElement( "Owner" );
name.appendChild( doc.createTextNode(myItem.getOwner() ) );
item.appendChild( name );

// Set Date
// Set Date.
Element date = doc.createElement( "Date" );
date.appendChild( doc.createTextNode(myItem.getDate() ) );
item.appendChild( date );

// Set Size
// Set Size.
Element desc = doc.createElement( "Size" );
desc.appendChild( doc.createTextNode(myItem.getSize() ) );
item.appendChild( desc );
}
}

return doc;
} catch(ParserConfigurationException e) {
e.printStackTrace();
}
return null;
}
}

private String convertToString(Document xml) {
try {
Expand All @@ -700,8 +739,9 @@ The following class uses the Amazon S3 API to perform S3 operations. For example
ex.printStackTrace();
}
return null;
}
}
}
}


### SendMessage class

Expand Down Expand Up @@ -1160,6 +1200,14 @@ The following HTML represents the **process.html** file.
<p>Choose the button to obtain a report.</p>
<button onclick="ProcessImages()">Analyze Photos</button>
</div>
<div>
<h3>Download a photo to your browser</h3>
<p>Specify the photo to download from an Amazon S3 bucket</p>
<label for="photo">Photo Name:"</label><br>
<input type="text" id="photo" name="photo" value=""><br>
<p>Click the following button to download a photo</p>
<button onclick="DownloadImage()">Download Photo</button>
</div>
</div>
</body>
</html>
Expand Down Expand Up @@ -1358,6 +1406,14 @@ The following JavaScript represents the **message.js** file. The **ProcessImages
var res = event.target.responseText;
alert(res) ;
}

function DownloadImage(){

//Post the values to the controller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Period at the end of the sentence.

var photo = $('#photo').val();
window.location="../downloadphoto?photoKey=" + photo ;
}


**Note:** There are other CSS files located in the GitHub repository that you must add to your project. Ensure all of the files under the **resources** folder are included in your project.

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package com.example.photo;

import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
Expand Down
Loading