Hwo to Upload to S3 From Intellij
Amazon simple storage (Amazon S3) is a service offered past Amazon web services that offers scalable, secure, and well performing object storage. This article volition go over how to upload files into Amazon S3 using Spring Kick.
Prerequisites
- Some noesis in Java and Spring Kick.
- Java development kit installed on your computer.
- Your favourite IDE. I use Intellij customs edition which is complimentary.
Amazon spider web services account
Earlier we start creating our awarding, head over to Amazon console, and create an account. You volition be given 12 months of free access to diverse Amazon web services that you can use to test diverse Amazon services.
After signing upwards, head over to Amazon panel and search for Amazon S3 in the search box provided in the console.
Amazon S3 bucket
After selecting Amazon S3 from the step above, create a new S3 bucket that we will use to store the files we volition be uploading from our application.
Proper noun the saucepan as jump-amazon-storage
and go out all other settings as default and so create the bucket.
Admission and secret keys
Create a new access key from My Security Credentials
navigation card as shown in the image below. Copy the admission and the cloak-and-dagger key generated as we will be using them to admission the bucket from the application we will be creating.
Creating the application
We will exist using spring initializr to create our application. Caput over to jump initializr and create a new Jump Boot application calculation h2
, bound boot dev tools
, spring data jpa
and bound web
as dependencies and so generate the project.
Unzip the downloaded project and open it in your favorite IDE.
Adding Amazon SDK dependency
Amazon SDK makes information technology possible to interact with various Amazon services from our applications. In the pom.xml
file add the Amazon SDK dependency every bit shown below.
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk --> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk</artifactId> <version>ane.11.931</version> </dependency>
Project structure
config/ |--- AmazonConfig.java |--- BucketName.coffee controllers/ |--- TodoController.java domain/ |--- Todo.coffee repositories/ |--- TodoRepository.java service/ |--- FileStore.java |--- TodoService.java |--- TodoServiceImpl.java SpringAmazonApplication.java
Configuration bundle
In the configuration bundle, nosotros accept two Java files, ane that authenticates with Amazon S3 and the other which contains the saucepan proper noun.
import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import org.springframework.context.annotation.Edible bean; import org.springframework.context.note.Configuration; @Configuration public course AmazonConfig { @Bean public AmazonS3 s3 () { AWSCredentials awsCredentials = new BasicAWSCredentials( "accessKey" , "secretKey" ); render AmazonS3ClientBuilder . standard () . withRegion ( "ap-south-1" ) . withCredentials ( new AWSStaticCredentialsProvider(awsCredentials)) . build (); } }
The AmazonConfig
course above is annotated with @Configuration
annotation to make it available to the Leap context equally a configuration course. With the Amazon credentials nosotros got from the Amazon console earlier we volition authenticate to S3 using the AmazonS3ClientBuilder
available in the Amazon-SDK that nosotros added to our pom.xml
ealier.
import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter public enum BucketName { TODO_IMAGE( "leap-amazon-storage" ); private final String bucketName; }
In the BucketName
enum above we pass in the bucket name that we created in the Amazon console earlier. The bucket volition be used to store all of our file uploads.
-
@AllArgsConstructor
annotation generates a constructor with thebucketName
variable in the enum. -
@Getter
annotation generates a getter for thebucketName
variable in the enum.
Domain package
In this package we accept the Todo
model that represents our Todo
in the database.
@Information @AllArgsConstructor @NoArgsConstructor @Builder @Entity public class Todo { @Id @GeneratedValue private Long id; individual String title; private String description; private Cord imagePath; private String imageFileName; }
-
@Data
annotation generatesgetters
,setters
,toString
andequals
methods for theTodo
class. -
@AllArgsConstructor
annotation generates a constructor with all the arguments for theTodo
class. -
@NoArgsConstructor
notation generates a constructor with no arguments for theTodo
class. -
@Architect
annotation creates a builder pattern for theTodo
class. -
@Entity
annotation makes theTodo
class a database entity. -
@Id
annotation marks theid
field equally a primary key in the database. -
@GeneratedValue
annotation makes theid
field auto-increment whenever a newtodo
is saved into the database.
Repository package
In this package, we have the repository course that extends the JPA CrudRepository
interface that makes it possible to perform various database queries.
public interface TodoRepository extends CrudRepository<Todo, Long> { Todo findByTitle (String title); }
Service package
@AllArgsConstructor @Service public course FileStore { private concluding AmazonS3 amazonS3; public void upload (String path, Cord fileName, Optional<Map<String, Cord>> optionalMetaData, InputStream inputStream) { ObjectMetadata objectMetadata = new ObjectMetadata(); optionalMetaData. ifPresent (map -> { if (!map. isEmpty ()) { map. forEach (objectMetadata::addUserMetadata); } }); endeavor { amazonS3. putObject (path, fileName, inputStream, objectMetadata); } grab (AmazonServiceException e) { throw new IllegalStateException( "Failed to upload the file" , east); } } public byte [] download (String path, String key) { effort { S3Object object = amazonS3. getObject (path, key); S3ObjectInputStream objectContent = object. getObjectContent (); return IOUtils. toByteArray (objectContent); } take hold of (AmazonServiceException | IOException due east) { throw new IllegalStateException( "Failed to download the file" , east); } } }
In the FileStore
form above, nosotros have the logic used to upload and download files from Amazon S3.
In the upload
method we pass in:
-
path
is the path on the Amazon S3 saucepan where the file volition be stored. -
fileName
is the actual proper name of the file being uploaded. It volition be used as the primal when downloading the file from S3. -
optionalMetaData
map contains the details of the file i.due east file type and file size. -
inputStream
contains the actual file that should be saved to Amazon S3.
ObjectMetadata objectMetadata = new ObjectMetadata(); optionalMetaData. ifPresent (map -> { if (!map. isEmpty ()) { map. forEach (objectMetadata::addUserMetadata); } });
The higher up code block loops through the optionalMetaData
map calculation all of the file information to the S3 objectMetaData
.
-
amazonS3.putObject(path, fileName, inputStream, objectMetadata);
saves the file to Amazon S3 bucket.
In the download
method:
-
S3Object object = amazonS3.getObject(path, cardinal);
downloads the file from the path passed in and with the file name similar to the key passed in thegetObject
method. -
S3ObjectInputStream objectContent = object.getObjectContent();
gets an inputStream from the object returned from Amazon S3. -
IOUtils.toByteArray(objectContent)
converts the input stream tobyteArray
that can be sent over Restful APIs.
public interface TodoService { Todo saveTodo (String title, String description, MultipartFile file); byte [] downloadTodoImage (Long id); List<Todo> getAllTodos (); }
The TodoService
interface above contains various methods that we will implement to be able to save and get todos
.
@Service @AllArgsConstructor public class TodoServiceImpl implements TodoService { individual concluding FileStore fileStore; private final TodoRepository repository; @Override public Todo saveTodo (Cord championship, Cord description, MultipartFile file) { //check if the file is empty if (file. isEmpty ()) { throw new IllegalStateException( "Cannot upload empty file" ); } //Check if the file is an image if (!Arrays. asList (IMAGE_PNG. getMimeType (), IMAGE_BMP. getMimeType (), IMAGE_GIF. getMimeType (), IMAGE_JPEG. getMimeType ()). contains (file. getContentType ())) { throw new IllegalStateException( "FIle uploaded is not an image" ); } //go file metadata Map<Cord, String> metadata = new HashMap<>(); metadata. put ( "Content-Type" , file. getContentType ()); metadata. put ( "Content-Length" , String. valueOf (file. getSize ())); //Save Prototype in S3 and so save Todo in the database Cord path = String. format ( "%s/%s" , BucketName. TODO_IMAGE . getBucketName (), UUID. randomUUID ()); Cord fileName = Cord. format ( "%s" , file. getOriginalFilename ()); try { fileStore. upload (path, fileName, Optional. of (metadata), file. getInputStream ()); } catch (IOException east) { throw new IllegalStateException( "Failed to upload file" , eastward); } Todo todo = Todo. builder () . description (clarification) . title (title) . imagePath (path) . imageFileName (fileName) . build (); repository. relieve (todo); return repository. findByTitle (todo. getTitle ()); } @Override public byte [] downloadTodoImage (Long id) { Todo todo = repository. findById (id). become (); render fileStore. download (todo. getImagePath (), todo. getImageFileName ()); } @Override public List<Todo> getAllTodos () { List<Todo> todos = new ArrayList<>(); repository. findAll (). forEach (todos::add); return todos; } }
In the TodoServiceImpl
above, we provide the implementation for the methods for saving and getting all todos
.
Controllers package
In this parcel, we have TodoController
class which handles the incoming HTTP requests.
@RestController @RequestMapping ( "api/v1/todo" ) @AllArgsConstructor @CrossOrigin ( "*" ) public form TodoController { TodoService service; @GetMapping public ResponseEntity<List<Todo>> getTodos () { return new ResponseEntity<>(service. getAllTodos (), HttpStatus. OK ); } @PostMapping ( path = "" , consumes = MediaType. MULTIPART_FORM_DATA_VALUE , produces = MediaType. APPLICATION_JSON_VALUE ) public ResponseEntity<Todo> saveTodo ( @RequestParam ( "championship" ) String title, @RequestParam ( "description" ) String description, @RequestParam ( "file" ) MultipartFile file) { render new ResponseEntity<>(service. saveTodo (title, description, file), HttpStatus. OK ); } @GetMapping (value = "{id}/image/download" ) public byte [] downloadTodoImage ( @PathVariable ( "id" ) Long id) { render service. downloadTodoImage (id); } }
Testing our uploads and downloads from the S3 bucket
Decision
Congratulations! At present that you learned how to upload and download files from Amazon S3, go ahead and implement the logic for uploading multiple files to Amazon S3.
Discover the source lawmaking here.
Happy Coding!
Peer Review Contributions by: Linus Muema
Source: https://www.section.io/engineering-education/spring-boot-amazon-s3/
0 Response to "Hwo to Upload to S3 From Intellij"
Post a Comment