Jquery Ajax + SpringBoot + Amazon S3 – Upload/Download Files/Images

In the tutorial, we show you how to Upload/Download files/images from Amazon S3 with Jquery Ajax and SpringBoot RestAPIs.

Related posts:
Amazon S3 – SpringBoot RestAPIs Upload/Download File/Image to S3
Amazon S3 – SpringBoot RestAPIs List All Files in S3 Bucket
SpringBoot – Upload/Download MultipartFile to FileSystem – Bootstrap 4 + JQuery Ajax

Technologies

  • Java 8
  • Spring Tool Suite: 3.9.4.RELEASE
  • Spring Boot: 2.0.4.RELEASE
  • Bootstrap 4
  • JQuery Ajax
  • Amazon S3

Goal

We create a SpringBoot project as below ->

jquery-ajax-springboot-amazon-s3 + project -structure

-> Upload/Download Form:

jquery-ajax-springboot-amazon-s3 + download-files

Practice

We create a SpringBoot project with below dependencies:


	org.springframework.boot
	spring-boot-starter-thymeleaf
		

	org.springframework.boot
	spring-boot-starter-web


    com.amazonaws
    aws-java-sdk
    1.11.379

FrontEnd
Upload Multipart-Form

resources/templates/uploadfile.html ->




    Upload MultipartFile
    
    
	%MINIFYHTML924da5e464f3f90bb59be5285c3489f314%%MINIFYHTML924da5e464f3f90bb59be5285c3489f315%%MINIFYHTML924da5e464f3f90bb59be5285c3489f316%%MINIFYHTML924da5e464f3f90bb59be5285c3489f317%%MINIFYHTML924da5e464f3f90bb59be5285c3489f318%
 

	

Upload MultipartFile to S3


%MINIFYHTML924da5e464f3f90bb59be5285c3489f319%
Ajax Post/Get MultipartFile

– JQuery Ajax to Post MultipartFile resources/static/js/postrequest.js ->

$(document).ready( () => {
    $("#btnSubmit").click((event) => {
        //stop submit the form, we will post it manually.
        event.preventDefault();
        doAjax();
    });
 
});
 
function doAjax() {
 
    // Get form
    var form = $('#fileUploadForm')[0];
    var data = new FormData(form);
 
    $.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/api/file/upload",
        data: data,
        processData: false, //prevent jQuery from automatically transforming the data into a query string
        contentType: false,
        cache: false,
        success: (data) => {
            $("#listFiles").text(data);
        },
        error: (e) => {
            $("#listFiles").text(e.responseText);
        }
    });
}

– JQuery Ajax to Retrieve/Download MultipartFile resources/static/js/getrequest.js ->

$( document ).ready( () => {
	// GET REQUEST
	$("#btnGetFiles").click( (event) => {
		event.preventDefault();
		ajaxGet();
	});
	
	// DO GET
	function ajaxGet(){
		$.ajax({
			type : "GET",
			dataType: "json",	
			url : "/api/file/all",
			success: (data) => {
				//clear old data
				$("#listFiles").html("");
				
				/*
					render list of files
				*/
				$("#listFiles").append('
    '); $.each(data, (index, filename) => { $("#listFiles").append('
  • ' + filename + '
  • '); }); $("#listFiles").append('
'); }, error : (err) => { $("#listFiles").html(err.responseText); } }); } })
Backend
Configure Amazon Client

S3Config.java ->

package com.grokonez.s3.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
 
@Configuration
public class S3Config {
	@Value("${gkz.aws.access_key_id}")
	private String awsId;
 
	@Value("${gkz.aws.secret_access_key}")
	private String awsKey;
	
	@Value("${gkz.s3.region}")
	private String region;

	@Bean
	public AmazonS3 s3client() {
		
		BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsId, awsKey);
		AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
								.withRegion(Regions.fromName(region))
		                        .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
		                        .build();
		
		return s3Client;
	}
}

Open application.properties, add aws configuration:

gkz.aws.access_key_id=// change to yours
gkz.aws.secret_access_key=// change to yours 
gkz.s3.bucket=grokonez-s3-bucket
gkz.s3.region=us-east-2
S3 Upload/Download Service

Interface S3Services.java ->

package com.grokonez.s3.services;

import java.io.ByteArrayOutputStream;
import java.util.List;

import org.springframework.web.multipart.MultipartFile;

public interface S3Services {
	public ByteArrayOutputStream downloadFile(String keyName);
	public void uploadFile(String keyName, MultipartFile file);
	public List listFiles();
}

Implementation S3ServicesImpl.java ->

package com.grokonez.s3.services.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.grokonez.s3.services.S3Services;
 
@Service
public class S3ServicesImpl implements S3Services {
	
	private Logger logger = LoggerFactory.getLogger(S3ServicesImpl.class);
	
	@Autowired
	private AmazonS3 s3client;
 
	@Value("${gkz.s3.bucket}")
	private String bucketName;
 
	@Override
	public ByteArrayOutputStream downloadFile(String keyName) {
		try {
            S3Object s3object = s3client.getObject(new GetObjectRequest(bucketName, keyName));
            
            InputStream is = s3object.getObjectContent();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len;
            byte[] buffer = new byte[4096];
            while ((len = is.read(buffer, 0, buffer.length)) != -1) {
                baos.write(buffer, 0, len);
            }
            
            return baos;
		} catch (IOException ioe) {
			logger.error("IOException: " + ioe.getMessage());
        } catch (AmazonServiceException ase) {
        	logger.info("sCaught an AmazonServiceException from GET requests, rejected reasons:");
			logger.info("Error Message:    " + ase.getMessage());
			logger.info("HTTP Status Code: " + ase.getStatusCode());
			logger.info("AWS Error Code:   " + ase.getErrorCode());
			logger.info("Error Type:       " + ase.getErrorType());
			logger.info("Request ID:       " + ase.getRequestId());
			throw ase;
        } catch (AmazonClientException ace) {
        	logger.info("Caught an AmazonClientException: ");
            logger.info("Error Message: " + ace.getMessage());
            throw ace;
        }
		
		return null;
	}
 
	@Override
	public void uploadFile(String keyName, MultipartFile file) {
		try {
			ObjectMetadata metadata = new ObjectMetadata();
			metadata.setContentLength(file.getSize());
			s3client.putObject(bucketName, keyName, file.getInputStream(), metadata);
		} catch(IOException ioe) {
			logger.error("IOException: " + ioe.getMessage());
		} catch (AmazonServiceException ase) {
			logger.info("Caught an AmazonServiceException from PUT requests, rejected reasons:");
			logger.info("Error Message:    " + ase.getMessage());
			logger.info("HTTP Status Code: " + ase.getStatusCode());
			logger.info("AWS Error Code:   " + ase.getErrorCode());
			logger.info("Error Type:       " + ase.getErrorType());
			logger.info("Request ID:       " + ase.getRequestId());
			throw ase;
        } catch (AmazonClientException ace) {
            logger.info("Caught an AmazonClientException: ");
            logger.info("Error Message: " + ace.getMessage());
            throw ace;
        }
	}
	
	public List listFiles() {
		
	  ListObjectsRequest listObjectsRequest = 
              new ListObjectsRequest()
                    .withBucketName(bucketName);
                    //.withPrefix("test" + "/");
		
		List keys = new ArrayList<>();
		
		ObjectListing objects = s3client.listObjects(listObjectsRequest);
		
		while (true) {
			List summaries = objects.getObjectSummaries();
			if (summaries.size() < 1) {
				break;
			}
			
			for (S3ObjectSummary item : summaries) {
	            if (!item.getKey().endsWith("/"))
	            	keys.add(item.getKey());
	        }
			
			objects = s3client.listNextBatchOfObjects(objects);
		}
		
		return keys;
	}
}
Upload/Download RestAPIs

– Expose Upload RestAPI in controller UploadFileController.java ->

package com.grokonez.s3.controller.rest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.grokonez.s3.services.S3Services;
 
@RestController
public class UploadFileController {
	
	@Autowired
	S3Services s3Services;
	
    @PostMapping("/api/file/upload")
    public String uploadMultipartFile(@RequestParam("uploadfile") MultipartFile file) {
    	String keyName = file.getOriginalFilename();
		s3Services.uploadFile(keyName, file);
		return "Upload Successfully -> KeyName = " + keyName;
    }    
}

– Expose Download RestAPI in controller DownloadFileController.java ->

package com.grokonez.s3.controller.rest;

import java.io.ByteArrayOutputStream;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.grokonez.s3.services.S3Services;
  
@RestController
public class DownloadFileController {
 	
	@Autowired
	S3Services s3Services;
	 	
    /*
     * Download Files
     */
	@GetMapping("/api/file/{keyname}")
	public ResponseEntity downloadFile(@PathVariable String keyname) {
		ByteArrayOutputStream downloadInputStream = s3Services.downloadFile(keyname);
	
		return ResponseEntity.ok()
					.contentType(contentType(keyname))
					.header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=\"" + keyname + "\"")
					.body(downloadInputStream.toByteArray());	
	}
	
	/*
	 * List ALL Files
	 */
	@GetMapping("/api/file/all")
	public List listAllFiles(){
		return s3Services.listFiles();
	}
	
	private MediaType contentType(String keyname) {
		String[] arr = keyname.split("\\.");
		String type = arr[arr.length-1];
		switch(type) {
			case "txt": return MediaType.TEXT_PLAIN;
			case "png": return MediaType.IMAGE_PNG;
			case "jpg": return MediaType.IMAGE_JPEG;
			default: return MediaType.APPLICATION_OCTET_STREAM;
		}
	}
}
Index Controller

IndexController.java ->

package com.grokonez.s3.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
@Controller
public class IndexController {
    @GetMapping("/")
    public String index() {
        return "uploadfile";
    }
}
Run & Check results
Upload Files

Upload Form ->

jquery-ajax-springboot-amazon-s3 + upload-file-succeed

File Uploaded in S3 ->

jquery-ajax-springboot-amazon-s3 + upload-files-on-s3

Retrieve Files

jquery-ajax-springboot-amazon-s3 + list-all-files

Download Files

jquery-ajax-springboot-amazon-s3 + download-files

SourceCode

– In application.properties file, change gkz.aws.access_key_id & gkz.aws.secret_access_key to yours.

– Sourcecode ->

SpringS3Amazon



By grokonez | August 5, 2018.


Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*