Spring Boot Tutorial | Spring Boot Full Stack with React.js | Full Course | 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi welcome to amigos code my name is Nelson and in this course I'm going to teach you how to build a cool application where you're going to be able to drop some images from a front-end app written in react and then store those images inside of a bucket so we're going to be using Amazon s3 as the you know leading cloud provider and pretty much you should be aware of Amazon AWS services and you know products and s3 is widely used throughout the industry so knowing how to store images files videos PDF text anything it's a really really important thing for you to know how to do it so for this course we're going to build everything from scratch so I'm going to show you exactly how to grab the access and secret keys from Amazon console and then I'm going to show you exactly how to bootstrap the application using springville as the backend and then we're going to create our react front-end that will talk to our back-end and in the backend talk to the Amazon s3 API so there is a lot to learn and I always always always suggest you to practice as I teach so I don't want to just sit and watch the videos but I wanted to practice because that's the best way for learning anything and then once you learn you can take the skills immediately and apply them to your own projects your own work you know pretty much University projects and a bunch of other cool places so there is a lot to learn if you haven't subscribed make sure to subscribe right now and without further ado let's get started alright let's go ahead and bootstrap our application so navigate to start or sprint or IO and right here you can bootstrap your application with maven or Gradle so let's go ahead and pick maven and then for the language go ahead a bit Java for the spring book version you can pick anything above actually to write so spring boot to version two so if you don't see 2.19 you can pick anything that is two point and then whatever then for the project metadata so right here go ahead and simply say your company so let me go ahead and say amigos code or your domain and then for the artifact I'm going to say image actually AWS image and then upload something like that right and then you can go ahead and you know specify more options such as the Java version so I'm gonna pick Java eleven and then I'm gonna leave everything as is and for the dependencies to add go ahead and simply so if I actually switch to this list right here you can see the full list of dependencies so the one that I'm interested is the spring web so I'm gonna pick that one and then what I'm gonna do is simply generate project and then I'm gonna save this to my desktop and there we go all right now that we have this zip folder let's go ahead and open up with IntelliJ so let me collapse this and then I'm going to extract this zip folder so let me extract it there we go and let me delete this zip folder so I'm gonna be using IntelliJ for this tutorial and if you want to learn about IntelliJ I've got a full course on YouTube teaching everything you need to know about IntelliJ so what I'm gonna do is simply click open and then let me navigate to desktop and then open up the folder that you've just downloaded and then go ahead and open up the palm dot XML and then ask Project and there we go so now maven its own instinct and we should have a project already bootstrapped so just give a second for indexing and there you go now let's go ahead and open up Google and let's go ahead and search for AWS and then Java SDK so right here so actually seem to say maven actually so right here let's go ahead and click on the very first link so this is the library that we actually need and you can see that it's the Amazon SDK for Java that provides an API for building software on AWS you can see right here Amazon s3 easy to SQL so on and so forth so let me actually grab that and then what I'm gonna do is expand this main folder so AWS image upload and inside of this folder we have palm dot XML so this is where you define all the dependencies for your project so inside of this dependencies section right here after the test so this one right here so spring book start the test let's go ahead and simply paste our at pennsie so that one and then simply say enable auto import and this will go ahead and resolve the dependency for you to just give you a second and there we go so everything has been resolved now we have this dependency that we can use to interact with Amazon AWS next let me go ahead and show you the credentials that you need from the Amazon console so that your server can connect to Amazon all right so let me go ahead and open up Chrome and what I'm gonna do is simply navigate to AWS and then if you don't have an account go ahead and register it doesn't cost you anything they give you I think it's two hundred and fifty hours for free for a year so that you can experiment with some of these resources or services that Amazon does provide and to be honest Amazon is the leading cloud provider out there everyone is using it and you should be aware of it and also know how to use it and understand how some of the services do work and today I'm gonna show you exactly how to use Amazon s3 so let me go ahead and simply sign into the console so if you don't have an account go ahead and create once you have the account go ahead and sign into the console so right here I guess you can see that I'm inside of the Amazon console so right here you have a bunch of services that they provide but the one that we are interested is the Amazon s3 so before we move any further what we need to do is to grab the Amazon credentials so go ahead and click on your account and then go to my security credentials and right here you can see that you can generate access keys so I think I'm only able to tweet to access keys but go ahead and pretty much generate one and then you'll be given D so if I go ahead and generate one so you can see that the limit has exceeded but go ahead and generate one and you'll be given two things the access key as well as the secret so as you can see once you download the secret you know able to see it right so if I click on it you can see that I can't see it and in fact let me go ahead and simply generate one so the oldest one right here is this one so I'm gonna delete it so I'm gonna type delete right here and if I go ahead and generate access key you can see that you get the access key ID as well as these secret so you can see right here so go ahead and download the file and then I'm going to show you how to use it so let me actually download the file and then put it inside of my desktop there we go and that is done so now that we have the access key as well as the secret let's go ahead and write some Java code that will take those and gives us an instance of the Amazon s3 client so that we can interact with buckets alright let's open up IntelliJ and inside or IntelliJ let me actually close this pump XML because we don't need it and go ahead and inside of SRC so source main and in Java and you can see right here that we have this class so if I open it up this is the main class that starts this spring pool application so what we're gonna do right here is simply create a package so inside of the main folder let's go ahead and create a package and right here simply call it config and by the way if you want to learn about IntelliJ I've got a full course on YouTube for free about IntelliJ next let me go ahead and simply name this as Amazon and then config and then enter and there we go now I'm going to annotate this class with ads and then configuration there we go so that spring instantiates this and anything that I have inside here next let's go ahead and simply say public and then Amazon and then s3 so this comes from the dependencies that we've added inside of our pom to XML so enter and then right here simply say s3 and then inside what we're going to do is simply say a WS and then credentials and then simply say AWS credentials equals two and then basic or actually new and then basic AWS credentials there we go and you can see that we have to pass D so if I press command P and you can also see the keyboard shirt that's down below we have to pass the access key and the secret key so let me actually go ahead and put empty strings for now and if I open up the CSV so what I'm Dooley's use terminal and I'm going to say cat and then desktop and then fourth slash access keys or CSV or you can open this file using the IDE so basically I want to get the contents so enter you can see that the access key is this one so I'm going to go back to IntelliJ and then put it in and then for the secret let me grab this and then paste it and there we go so now we have the credentials now what we need to do is simply say return so we're going to return and then Amazon s3 and then client builder and then dot standard so this is using the Builder pattern so let me put this on a new line and then down new line as well and then dot width and then credentials and we want to pass the Grinch's so new AWS and then static and then credentials provider and inside pasti credentials just like that and then simply say dot and then build there we go now we have this class that will give us the s3 client right here so we can use it now obviously this is missing an annotation and that is at and then pin so that spring instantiates this class right here so an instance of Amazon s3 with these configurations so that we can inject in other classes next let's go ahead and create the packet that we will be storing and retrieving images from alright go back to the Amazon console and go back to s3 so click on services s3 so you can search for 3 or you can see in the history or you can pin so you can clean s3 right here so whatever is easy for you so I'm gonna click on s3 and then you can see that I already have couple of buckets right here right so I've got one for my website and another one for elastic Beanstalk so I was doing some experiments and also you can see this one testing image 1 2 3 now let's go ahead and create a new bucket and the bucket name let's go ahead and simply say amigos and then code - and then image - up load and then - 1 2 3 so this is the name of the bucket and then obviously you can specify the actual region so for me let me go ahead and simply say Ireland so Ireland there we go and you can copy settings from existing buckets but leave it as is and simply create and there we go so now we do have this bucket right here called amigos code image upload one two three so the bucket names they must be unique so if you have a bucket name called amigos cold - images - upload one two three it won't work so it has to be a unique packet right so go ahead and pretty much just use your company name or your name or generate you know very random bucket name for your own use so what I'm gonna do is simply grab this name so this is the name of the bucket so actually let me click on it and then I can grab the bucket name from here so I just copy that and currently you can see that the bucket is empty so what we're gonna do is go back to IntelliJ and let's go ahead and create a new package so let's go ahead and simply create a new package and right here simply call it buckets and then inside of this bucket let's go ahead and create a kneel class and this will be an enum so with a big enum from this drop-down and then right here simply say bucket and then name and then press ENTER and what we're going to do is simply define an enum called profile and an image so this will be an enum that we can use through our code base that will have the current D the following value so amigos code image upload one two three now obviously that needs some work so let's go ahead and simply say private and then final and then string and then bucket and the name and I'm missing a semicolon there and what we need to do is simply create a constructor for this just like that refactor and then factor and there we go so now we have this enum that takes a bucket name and then we can use only this innum to get this specific value so let's go ahead and generate the actual getter there we go and we are done with this class next let's go ahead and pretty much create our service that will store images to this specific bucket all right so I just want to mention that you saw that we created the s3 bucket via the Amazon console we could have created a bucket within our java application right so usually that's not the best practice when it comes to create like infrastructure right because a bucket is a piece of infrastructure so you either create a manually or better you might use something like CloudFormation or terraform so just to let you know that you know there are other options in a way that you can create buckets but if you want to create buckets through code I would not recommend it if you have any questions go ahead and message me otherwise let's move on all right so let's go ahead and create a new package so inside of this package let's simply go ahead and name it as file and then store and then enter and now inside of this package let's go ahead and create class called file and then store just like that enter and now we have this class that will in that will use this this class right here that we told sprinkle to make it available for us to inject and then store images so basically we can store not only images but you can store anything that you won't really write a file zips you know pretty much anything that you can think of so now let me simply go ahead and open up the file so class let me go ahead and annotate this with ADD and then service and what we're gonna do is I'm going to say private and then final Amazon s3 simply name is s3 and then add to constructor and right here we're going to auto wire so this is using the pendency injection and again you can learn more about this go ahead and check my youtube channel where i've got plenty of videos on the ben's injection as well as spring book now let's go ahead and pretty much implement our very first method so we will implement the save method and then the download method later on so what we're gonna do here is simply create method so public and then voice so we're not going to return anything and people say safe now what we need to specify right here are a couple of things so one we need the path so the path will be the bucket name plus any subfolders that you may or may not have so let me go ahead and say path and then we're going to have the foul name so string and then file and then name and let's also have an optional and this will be an optional so actually let me put this on a new line so you can see exactly everything so right here will be an optional of a map so a map of strings and then string right here and basically this will serve as the metadata that we can pass to store images or files right so you can include the content type the content length so on and so forth so let me simply say optional and then meta data there we go and then comma and then we're going to pass the actual input and in streams so this is what gets saved to Amazon s3 bucket so I'm gonna show you exactly how we're going to get this from our client but for now let's go ahead and simply say try and then inside of this try block what we want is to say s3 and then don't and then you can see that we have a couple of methods but the one that I really want is the put method so right here I'm going to pass the path the file name and then the input stream and then the meta data right so meta and then data so what I'm gonna do actually is let's go ahead and create this metadata so let me go ahead and simply say object metadata and then object metadata equals two and the new object metadata and now right here I'm going to say optional don't and then if present so we'll have the actual map so inside of this map I'm going to say if and then map dot is empty and I'm actually going to flip it so me to flip it just like this so if it's not empty what I'm going to do is simply say map dot and then for each I'm going to say object method data column column and then add user metadata taking the key as well as the value so if you want to find out exactly how this is being used so it's like that right so you can see that for each takes the key and the value and I'm saying add actually object metadata add metadata so inside of this object right here there is a method called add user metadata passing the key and value from this map right here right which is this one if is present but we can use method reference so just like that and it looks much neater and there we go and in fact this should let me rename this to metadata so just like that and then just like that and you can see that this error now went away now if we are successful so if we are successful with this operation right here which might throw an exception we simply store the foul otherwise we're going to catch let's go ahead and catch D Amazon and then service exception right here and then simply say E and then for now I'm simply going to throw new and then illegal state exception and then I'm going to say failed to store content to store file to s3 and then comma and then pass the actual exception right and there we go so now we have this method that saves files to Amazon s3 now let's go ahead and actually build this application incrementally ie let's go ahead now and define the actual model and then the actual API and then let's build the front-end and upload a image and see that it works and then we can improve the application progressively alright let's go ahead and find the actual model for this application so if I go back to the actual diagram so right here so basically we want to upload images for let's say profile users right so a profile user coming from our react front-end can upload an image right so we can upload an image for a profile user so let's go ahead and define the profile user class or a model so inside of the main package so let's go ahead and create yet another package and let's call this package as profile and let's create now a new class and we're going to name this class as profile and then user or user profile I think it sounds better so user and then profile now this user will have a few things so one we will have an ID for this profile user so private and then you it and then this will be let's actually say profile Ashley user and then profile ID and then let's go ahead and simply have a user name so private and then string and then user name and finally because we need to store the actual image let's go ahead and simply say string and then profile and then image and then key so this will be the actual watch is not key but let's simply say profile or user profile and then image and then link and let me simply add a comment saying that this will be the s3 and then link or actually key right so now let's go ahead and turn instructor just like that and let me put this on in your line so you can see everything let's also generate some getters and setters or actually just like that looks so get it and setters just like that and finally we will need the equals and hashcode so let's go ahead and say equals and hashcode and right here go ahead and pretty much just select the default there and then simply say next next and then select all non-members just like that and then finish so right here I'm going to change something right so right here instead of saying user profile indeed or equals because this might be no and if it's null it will blow so what I want to do here is instead of say equals I'm gonna say objects objects dot and then equals so right here so I'm going to show you exactly what this means in a second and I don't want this so no and then don't ask again so let me actually remove that and then this will be a comma there and let me grab this and then place it there there and then right here simply add the opening of parentheses and then remove that equals there watch the apprentice and then the same here so user profile just like that remove the equals and the parentis and then comma so basically so if I save this and then indent things so if I open up this object of equals you can see that it's saying whether a equals to be right or a not equals to null and a dot equals B so basically right here we have our now check which will make things much better so I think you can use guava and guava then you know does all of this but because we've used the defaults and when generated the shoe equals from Java 7 this is what we get so there we go now that we have our model called user profile let's go ahead and create a fake database where we're going to return some fake users to our clients all right so let's go ahead and pretty much just have a another package and right here simply say data and then store and let's go ahead and simply create a new class and simply say fake and then user profile data and then store and then press enter and there we go now let's go ahead and simply annotate this with at and then repository and let's go ahead and simply have a private and then static final and then list so this will return a list of user and then profile and let me simply say user profiles equals two and then new and then array lists just like that and then inside of a static block let's simply add some user profiles so user profiles dot and then add new and then user profile and then right here let's simply go ahead and say you it don't run the MU it and then and then for the username let simply say Janet and then Jones and then what we need so come on P and then we need to link so the link I'm going to say no right there and let's add another one and in fact me put this full screen so you can see so I'm gonna duplicate this and then right here I simply say Antonio and then jr. just like that and then also for now let's hit the user profile image link no and there we go so what changes I want to make so because this user profile image link can be no let's go ahead and open up the profile actually use a profile model and right here so when we return the so right here so where we get the user profile link let's make this an optional and then what we're gonna do is simply return optional dot of inaudible just like that so anyone looking at this method or calling this method knows that this might be no and then they can use optionals and streams to code against it which is really cool so there we go now that we have this datastore let's go ahead and pretty much have a method so let's go ahead and seem to say public and then a list and then user and then profiles and then get and then user profiles there we go and now simply return and then user and then profiles there we go and we are good to go so now that we have this fake user profile let's go ahead and create the API that will return this list right here so if I go to the diagram again so we're going to build this part right here so currently we've been touching a lot on the service on the service side right here but let's go ahead and define this API for now so but next let's go ahead and create a method that the client can hit and then they get D and then they get the list of user profiles in our database and if I expand this so inside of this package right here so profile let's go ahead and create class and simply named it as profile and then controller or actually user profile and then controller and then enter and there we go so now let's go ahead and simply annotate this week at and then rest and then controller and then controller and then let's go ahead and also define the add and then request and then mapping and right here I simply go ahead and say API and then v1 and then user - profile and then inside let's go ahead and define a method so let's go ahead and say that we want to have a method that will return a list of users so public and then list and this will be a user profile and simply say get and then the user and then profiles there we go and for now let's simply return and then no for now so now let's go ahead and simply say this will be at and then get mapping and that's it now let's go ahead and define a service class so user profile and then service and let's also define the class that interacts with the database so let's go ahead and simply say user profile data access and then service so the job of this class will be also at and then repository so this will be a repository now inside right here let's use some dependency injection so I'm going to say private and then final fake and then user profile a store and let's add this to constructor and then ultra wire there we go and if I remove that line now let me go ahead and simply say this will return a list and then of user and then profile there we go and then let me simply say get and then user profiles and guess what we're going to return the fake actually fake user profile' datastore don't and then get user profiles so the reason why I'm doing this is because you can use then dependency injection to change this class right here right so if you implement to an interface and I explained this on my videos a lot how to implement an interface and then how you can switch implementation so that's why I'm actually you know injecting this class right here so that then you can use you know dependency injection to change implementations right now we are using a fake data store or a fake database but if you want to use for example my sequel or Postgres you can pretty much change just one ladder you can too much just change one line of code and then you switch to a real database so if you wanna learn more about that go ahead and check my videos where I teach all of that so now so now that we have this user profile data access service let's go ahead and you open up the user profile service so this is where all the business logic really happens so for us we simply have one method and really there's no business logic at the moment so user in in profile data access service and again let me inject this so at and then also wired and this will be at and then service so right here again let me simply say this will be a list or in fact let me grab the exact same thing here and then paste it here and then this will be user profile data access service and there we go so now it means that I can take this User Profile Service go back to user profile controller and then simply say private and then actually this should be final and then right here let me simply inject and then add and then also wire so now you can see how things are connected so get and then user profiles now let's go ahead and pretty much just fire up the application and see if we get an API up and running so let me go ahead and open up the AWS image upload application and in fact I'm going to rename this to main of course I want to rename that and then open up main and then simply run this main class and there we go so if I show you the logs you can see that right here Tomcat initialized with port 8080 now if I collapse this and open up user profile controller now take this path right here and then go ahead and simply open up your web browser simply say localhost and then 8080 fort slash and then paste API v1 user profile enter and voila you can see that we have two users in our database so this is coming from our fake database but you get the idea so if you were to implement to a real database it would be the exact same thing so you can see that we have Janet Jones here and Antonio jr. so this is all for this part next let's go ahead and implement the the upload endpoint so this one right here so when the client sends us a file for a particular user we then want to update so we want to update this link right here with the correct image profile link alright let's go ahead and implement the image upload endpoint so let me collapse this and inside of the user profile controller let's go ahead and define a new method right here so let's go ahead and simply say public and then this will be void and right here what we're gonna do and then let's name this as upload and then the user pro file and then image and let me add some curly brackets there and what we're gonna take from the client are two things one we want to take the path variable so add and then path variable and this will be the actual user Pro file and then ID and this will be your weight and then let me actually name this user profile and then ID just like that and let me expand this so now we have the actual user profile ID coming from the actual path so this will allows us to assign an image to this profile ID or to this user and the final thing that we need is the actual file so for this go ahead and simply say add and then request and then program so this will come as request param and I simply named this as file and you'll see how we're going to set this from the front end and simply say multi and then part and then file just like that and then simply save file now let me go ahead and simply indent things properly and there we go now what we need to do here is very simple they simply call our user profile service and then let's simply say dot and then upload or in fact let's take the exact same name and then simply pause the user profile ID and then the file just like that and then let me go ahead and create this method and just leave it as it is and there we go so let me go back to this controller because we haven't finished so the next thing that I need is to say that this will be at and then post and mapping and then inside of this post mapping I need to say that I'm going to consume so consumes and then this is equal to media type multi-part form data and then value and then I'm going to say that I'm going to produce and then media type dot application and then adjacent value and then right here let's simply finally defined the actual path so oh in fact let's define the path up above right here and remove this comma so path actually path not params so path equals two and then this will be so this will be this user profile ID and then and this comma right here and then simply say fourth slash and then image and then forward slash and then download so there we go so this will be then as follows so the path for this will be we're going to take this ID right here and then simply say fourth slash the actual ID and then for slash image forward slash and then upload but you're going to see how we're going to define this in a second when we implement the react application and there we go so now this API will be able to take the profile ID as well as the file and then use this use a profile service to upload images so currently this is empty we're going to implement it next all right so right now I'm not going to implement the entire logic inside of this method called upload user profile image but I'm gonna leave some comments on what we need to do when we get to this point so one we have to check so one check if image is not empty and then second we want to check if actually I've got type up so empty then I will check if file is an image I then want to check whether so I'm just thinking out loud right here so I then want to check whether the user exists in our database and then if so grab some meta data from and then file if any and it should be with B and then finally what we need to do is simply so five so this will be store the image in s3 and let's simply say and update database with s3 and an image and then link right so we want to update so date base basically we want to update so let me show you so we want to so we want to update this user profile image link and in fact let me simply say update database and then just like that right so we want to update this so for now what I want to do really is nothing I'm not going to implement anything because I want to show you exactly how we are going to get to this point right here where we have the file so now let's switch to don't end where I'm going to show you how to set up the react application and then how we're going to send a file from the front end and then I'm going to show you how to add a breakpoint so you can see exactly the file at this point so once we have the file so once we have the file we can implement all of this logic so for now let's switch to JavaScript and react alright let's go ahead and bootstrap the react front-end for our application so let me quickly go to the diagram and basically let's go ahead and implement this part right here right so where the client will be written in react and then we will issue get and post requests to our API so go ahead and open up Google and search for create react app and right here in this very first link so by facebook create react app so this allows you to bootstrap your react application so if I scroll down you can see that you simply have to say npx create react app and then give it a name and then you say CD into that so you change directory and then simply npm start and then you get this app right here so I think they have screen shot no they don't well I'm gonna show you exactly how this works so go ahead and make sure that you have note installed so if I open up Chrome and then she will say node and make sure that you have node installed in order to have NPM as well as npx so what I'm gonna do is go back to IntelliJ and right here you can use the terminal right within IntelliJ so let me click on it and if you don't and if you want you can also use your own terminal so right here so just use whatever you want but I'm showing you other options to use terminal so IntelliJ is really powerful so right here so what I'm gonna do is if I do an LS and then - al you can see that this is the current folder structure and in fact if I expand the project tab so right here so whatever you see here you can see that is the exact same thing so right here you can see that we have source so source is right here we have the Palm D'Or XML so on and so forth so what I'm gonna do is simply say CD so change directory into SR see and then within that we also have main summer press enter and there we go now within Maine so this is where I'm going to run to this command so if I go back to Facebook creator app so right here I'm going to issue this command right here so let me copy that and then go back to IntelliJ paste that in and then right here I'm gonna change this to front and then end just like that and then press Enter and you can see that this is now going off and you know downloading everything and bootstrapping a react app that we can run within seconds so just give me a second it's downloading all the node dependencies and there we go so you can see now we have this message saying happy hacking and we have a bunch of commands right here so we have how to start so we need to city into front end and then simply type NPM start and you can see right here we have NPM run build tests and then eject and also you can see that we have our front end right here so this is awesome so what I'm gonna do for now is I'm going to clear the screen and then CD into front end there we go and now I'm going to type NPM and then start and there you go so you can see now that we have this react application basically this is what the bootstrap does so now that we have this bootstrap application let's go ahead and change it to according our needs and also perform a get request to our back-end to pull this information right here so we're going to hit this endpoint localhost API version 1 and then user profile and we should get this array right here you can use IntelliJ Ultimate Edition for web development but because I'm using the community it doesn't have support for JavaScript so I'm actually using this one because I know most of you will be using the Community Edition however if you are using the ultimate you can use Ultimate Edition for JavaScript even though I think that this IDE vs code is the best IDE out there for web development so go ahead and download it to follow along with our known issues and I highly recommend it so let me go ahead and open up the vs code and what I'm gonna do is pretty much just open so I'm going to open inside of the desktop I'm going to open the app and then navigate to source main and then open the front end folder so I'm going to open and there we go so now you can see that I've got the bootstrap application and in fact if I go ahead and pretty much just open up SRC and then after GS and right here let me simply say hello and then react and then save this go back to the web browser you see you should see that this reflects immediately so then react and then ello react let's go ahead and make some changes to this web app according to our needs so what I'm gonna do here is pretty much remove everything so actually I'm going to remove everything right here so I really don't need everything here so I'm gonna remove everything within D header so I'm gonna delete that there we go and if I save this go back to the web browser and you can see that now this has nothing so we are good to go so the you know the files here they're very soft expand hurry and if you wanna learn more about react I've got some videos on react and you know just follow along and we'll be super easy so what we need to do here is first let's go ahead and download a dependency called ratios so aces allows us to perform HTTP requests to backends so right here so what I'm going to do is go through IntelliJ and what I'm gonna do is actually cancel this and for now I'm going to keep away from IntelliJ someone cancel that and then if I collapse this if I go to my web browser refresh you should see that the site can't be reached so what I'm gonna do is within my time you know so I'm gonna use my terminal I'm going to CD into desktop inside I've got the AWS image upload project and then SRC main and then front-end there we go so now I'm going to say NPM and then start and we should get the exact same thing there we go so now let me actually Council and then simply say NPM - and then capital s I for install and then simply install a CIO's press ENTER and the Ricoh succeed this was really fast and if I go ahead and pretty much just say cat and then package dot JSON or actually JSON should see that we have the ASIS right here right so in fact just let me show you from within that vs code so inside of package JSON you can see that we have the ACS right here so this is a library that we've just downloaded now let's go ahead and start the server so NPM start wash lips start and let me go back to vs code and open up the app GS and right here let me go ahead and pretty much go ahead and say import and then eight and then a ce o--'s from and then issues and from react what i'm going to import are two things so i'm going to import the use and then state from react and then use and then effect just like that so i'm gonna be using some hooks and hooks is a new way of creating functional component and i've really experiment with it i don't know you know a great deal about it it seems really awesome and it makes your code look much cleaner so now let me go ahead and write here so what i'm gonna do is simply create a new function so i'm going to say const and then i'm going to call this as user capital S and then profiles just like that and this will be an hour function and what we're gonna do here is actually I need an equal there so equal and right here I'm going to say Const and then get actually French and then user and then profiles and then this will pretty much just invoke asia's so I'm going to say ratios dot and then we have a get function and we didn't this get we have to pass the URL so remember correctly the URL was this one right so localhost 8080 let me copy that and then paste it in and then what we need is simply dot and then then so this returns a promise and then inside we have the response so what we're gonna do for now let me simply say console dot log and then res so on a log the rest so the response we see exactly what is inside and then end up with semicolon so now after this what I'm going to do is simply say use and then effect and then inside of this I'm going to pause this function right here and I'm going to simply say get and then users so once you don't get uses the fetch user profiles so basically this is similar to component did mount if you ever done any kind of react I'm gonna invoke that and then just like that now what I'm gonna do here is also pass an empty array and this pretty much says if there is anything that changes inside of this list this used effect will be triggered again in our case we haven't got anything just yet but just add it and it's good to know why it's here and I've also noticed that I've removed the Eco from here so just let me add it back save that and everything is good to go now inside of this Dave right here simply go ahead and say user and then profiles and this is the actual component that we've just created right so this is a functional component now what I'm going to do is simply save this and then let me go back to Chrome and open up the application so right here and you can see that we are missing a statement so let me actually say that I need to return basically let me simply return and an h1 for now so hello and then go back you can see that we have a little right here but now if I inspect the console so I'm interested in the console and then go to console and all right here you see that we have a connection refused and that's because the back end is not up and running so let me simply start the back end there we go up and running let me go back and now refresh and there we go so you can see now we have a different so access to this URL from a region was blocked by course so this means that when you have an application which is trying to communicate to your back-end on a different host you get this course error so this is to prevent from malicious attacks where you know you have different hosts accessing your back-end so let's go ahead for now and ignore this so let's go ahead and open up the back end so inside IntelliJ go ahead and open up D so if I click here so go ahead and open up user profile controller and at the very top so let me put this full screen go ahead and simply say add and then cross and then origin and then right here we'd like to say that we will accept from anywhere so you shouldn't really do this so in production or if you are deploying this you should be really know exactly what to allow to your endpoints but for now because we are testing things locally I'm going to enable this to localhost 8080 I could see if in say localhost 80 or actually 3000 but you might have you know different front-end applications locally running in different ports so by saying star you simply enable everything now let me go ahead and restart this so I'm going to say stop and rerun there we go now if I go ahead to my front end and then refresh you can see that now we get this status code of 200 and we have the data array so inside you can see that we have the data and it contains our two users so there we go so we've managed to connect to our back-end next let's go ahead and pull some of this information right here into our application and then we will add the capability to upload files all right so let's go ahead and take this data array right here and shovel into our screen so currently it says hello but eventually we want to have all the names right here so what I'm gonna do is go back to this code and right here so where we fetch the users so right here you can see that we we go to our back-end and then we console dot log the response but remember right here the response contains the data property so inside what I'm gonna do is simply say Const and then user actually MZ will say data equals to read the odd and then data just like that so now that we have the data what we need to do is to set the state so let's go ahead and before this fetch state let's go ahead and simply say Const and then right here simply add you know curly brackets and then user Pro files and then simply say set user profiles and this will come from equals to use and then state the initial state will be an empty array so what we're gonna do now here is simply say set and then user profiles and I'll pass data in front listen to say res dot and then data just like that and delete that so now if I save this you should be setting the state right here now that we have the state we can simply map it into whatever we want so right here where we returned the h1 so right here instead of return hello what I'm going to do is simply say user profile so this user profiles is this one which is set by this function and then don't and then map and inside of that we have the actual a user and then actually let me say user profile and then we also have the index right here and what I'm going to do is simply add an hour function and inside right here for now let's simply say return and then we're going to return a div and inside of actually let me add parentheses because I think it looks cleaner just like that and then just like that and then and there as well and just like that and then inside what I'm going to do is simply add an h1 so right here so right here let me simply and the actual user profile so user profile dot and then user Pro and then file and then ID so we get the ID or actually let's go ahead and simply say user name and then let's have a P tag for the ID so a user and then profound dot user profile ID just like that so now if I go ahead and pretty much just add the actually so let me add the key right here so because they have to be unique this will be the actual index so if I save this and then go back to Chrome and right here you can see that we have Janet Jones as well as the actual ID right and this should be it so you see that now we are rendering the information coming from our back-end so also you can see that so right here so if I open up the data so we have the image profile link but I'm not going to add that because this will be a real image in a second next let's go ahead and use drop zone which is a vibrator allows us to send files to our server all right so navigate to react drop zone on github and I'm gonna leave a link for this ripple so you can follow along but basically this repo allows us to drop files so you can see right here it's very slick so the installation is very straightforward you simply say npm install - save red drop zone and then the end and then the usage you can see right here we simply have this functional component and then we are ready to go so let's go ahead and install this package so I'm gonna grab that and then open up the terminal I'm gonna cancel out of this place that NPM install - tar save reactor up zone enter just give you a second and there you go so now we have the library installed so let me seem to say NPM and then start and wallah so you see that everything is working fine now for each user so for each user profile let's go ahead and add the drop zone where we can upload an image for that specific user so what we're gonna do right here is very straightforward so let me go ahead and open up the s code and actually let me go back and steal some code so right here I'm going to grab this and then go back to vs code and let me paste it here and we also have to import this so let me go at the very top they start in and we also have to use the use and then callback so right here you use go back and it's that simple so now what I'm going to do is for each user so when we loop what I'm gonna do is simply use the drop for actually my drop zone so in fact let's go ahead and simply say drop zone there we go and then if I save this and now if I open up my browser right here you can see that we have drag and drop some files here so what I'm going to do for now is you see right here inside of this on drop so we are using a callback so whatever so what I'm gonna do is so I'm going to say Const and then file equals to accepted files and then I'm gonna grab the first file and right here I'm gonna simply say console dot and then log and then file and then save this and now what I'm gonna do is pretty much just drop a file and see what we can so right here let me simply close this actually I need this so you can see exactly the logs so let me expand it even further just like that now if I drop this access Keys dot CSV so watch this so I'm gonna take this and then you see that this will change so you can see that as I put the file there I'm actually happened so quickly so basically right here you can see that we are logging right here so this is the file so actually let me do it again so let me clear this and then let me actually grab the file and you can see that the text changes so drop the files here and if I do the same for the other one you can see that it's changing so then actually drop it here and you can see that we get full information about the file so if I make this bigger so you can see right here so this is a file and we get a bunch of information about it so the last modified the name the path the size the type so it's text CSV and you know this is the actual file that we can now send to our server which is pretty cool so now let me go ahead and simply made some changes so in fact I'm gonna grab this drop zone and put it here and then what I'm going to do right here is simply add a breakpoint at the very end so right here simply add this BR so we have some space and also at the very top let's add to those so BR just like that and then another one just like that so basically we will have the profile image right here so to do an in profile and then image so let me simply save this and then go back to Chrome anything see that this is looking much better also let me go ahead and add some CSS styling so right here open up the index dot s CSS and then for the background so go ahead and sit back and then ground so I'm actually background and in - color so let's pick a color so in fact let me use this color picker right here save this now if I open up my front end and you can see that it's looking much nicer and also you can see that we have the tracking drop some files here let's change that text as well so this will be dragged drag and drop so right here profile and then image or click to select profile and then image just like that and then right here so drop D image and then here just like that save go back and you can see drop the image here so obviously this is not an image but next let's go ahead and download some images that we can use all right so navigate to pixels comm and right here you can download free images so let me go ahead and search for a boy so right here and let's get this guy right here so I kind of like this picture so I'm gonna download it so free download into my desktop so let me simply say this will be what was the name so this was like if I cancel this so this was Antonio jr. so let me grab that and we did the image go so if I download again so that will be Antonio and jr. so if I now save this there we go and then we have Johnny Jones so let's actually search for a girl so let me simply say girl and then let's actually say that this is Johnny Jones so free download and then paste that in and then save there we go and we have two images so if I pretty much now close this and I'm gonna leave a link to pixels so you can follow along as well so now so you can see that we have two images right here and I can take this so let me actually open the console and expand that like that console and right here so if I take Antonio jr. and then drop it you can see right here I can drop it oops that didn't work so if I take it again drop it there you see that now we have the frown so right here you can see that the name is Antonio jpg the size the type image JPEG and basically now we are ready to take the file and send it to our server the same with Janet Jones so if I take this file put it here drop it and see that we have Janet Joan information actually the foul or actually the image for Janet Chun so right here you see all the information and also you can click here and pretty much just grab the file so I'm just showing drag and drop because it's cool but you have both options so next let's go ahead and implement the functionality that will take these files and then upload them to our server all right so let's take these images and implement the functionality to upload them to our server which then so if I open up the diagram again so right here so we will upload the images and then it will land on our API so this or actually layer and then it will pass through the service and in the service will store them in the s3 bucket as well as the database so we will update the actual profile image link inside of our database so remember so before we did have this API right here so this method right here called upload user profile image and just to mention that I had a so this shouldn't be download she should be upload and I've mentioned that previously so this should be up and then load because we are uploading images but we also will have the download method so right here you can see that we have to pass the user profile ID and then forth slash image and then upload right here and then the actual file right so we have everything that we need to pass it to our server so let's go ahead and open up vs code and right here so what we gonna do is so you see that we have the actual foul right so what I'm gonna do here is simply create a form data so this is what we need to send the actual file as a multi so right here as a multi-part file so right here I'm gonna say Const and then form and then data equals 2 and then new and then form data so now let me add parentheses and then end done now what I'm gonna do is you say form data and then dot append and then right here I'm gonna pen the actual well and then pass the foul so right here so this name file has to be the same as this one so this will be available to us through request paramo this is very important now let me go back and now that we have the file appended to this form data let's go ahead and use a SEOs so and actually add some spaces you can see exactly what's happening so let me use a SEOs so I'm gonna say a SEOs and then dot and then post and then guess what so remember so that will be localhost and then the actual API v1 user profile and then profile ID image and then upload so let's actually grab the Euro from here so this will be the same thing and then go here and then let me actually append it here and what we need now is to pass the actual profile ID so let me use a bad tix here and right here I want to say 4th slash and then I'm going to use and dollar sign and I'm gonna pass the profile I'm actually user Pro file and then ID and we're going to define this in a second 4th slash and then image forward slash ops almost me made the same mistake so upload and download upload there you go so right here so image upload is this one right here right and you can see that we will possibly use a profile in a second so now how do we get the user profile ID so this is very simple so we will get it from props so right here I'm going to say user profile ID and then when we define this component we can simply pause the user profile ID so one module here is simply the structure everything so I'm gonna pass everything because I know there is a a field called user profile ID so I'm gonna say right here so dot dot and then user and then profile so this is the same as if I was to do this so let me actually say user profile ID equals to an user actually user profile don't user profile ID right so this is too much I'm just gonna do that and now we have access to the user profile ID now let's actually finish up this post method so inside of a sheõs what we need to do now is actually pass d so comma and then form and then data and we also have to pass some headers so this will be in the form of an object and then inside have headers and then we'll have the following so I'm gonna have the content and then - and then type and remember what does the server accepts so remember so the server accepts a multi-part data value so let's actually go ahead and simply say multi and then part four slash and then form - and then data and there we go this should be everything that we need to send files to our server now obviously we can pass the dot and then then right so then and for now let's say console dot log and then let's simply say file uploaded successfully and then it's out of the catch and then air so that's the air and for now they simply console the log the actual air so dot log and then air oops just like that and then end up with semicolon and I think we are done so next let's go ahead and test this entire logic and see if it works alright let's go ahead and test things out so first let's make sure that the front end is I've been running with no errors so if I expect you can see that there is no errors this is just a warning and if I close this so let's go ahead and open up the back end and go ahead and stop the back end so I'm going to stop it and what I'm gonna do is put a breakpoint right here so put a breakpoint right here and then debug so let's debug this so basically when the client hits this hand point right here so this endpoint the actual call will stop here and then we can inspect the values so now let me go back to the web app and let me go ahead and simply drop a file so what I'm going to do is simply grab and Tony Junior profile picture and then simply drop it right here and then this should work and oops we have an error so all is expected right so it never works the first time so let me go to console and you can see that we have a 500 so we actually try to upload the file but the server responded with 500 so let's actually inspect the server and right here you can see that we have a bunch of errors and let me actually show you what the error is so right here you can see that the field file exceeds its maximum its maximum permitted size so basically it means that the file is too big so what we're gonna do is actually override the defaults so up like the project tab and inside of resources folder applications or properties let's go ahead and simply say spring dot servlet don't multi-part - and then dot and then max die foul - size equal to and then let's actually be generous so 50 MB now let me actually go ahead and debug again so there we go let's actually try the exact same thing so let's actually close this and then if I try and upload the file again you can see that this time it works so the file was accepted by our server and you can see that it hit the actual breakpoint so if I put this whole screen you can see that we've hit the breakpoint so right here we have this inspect tool so right here we can inspect the contents of you know all the fields or the objects on it so forth so you can see that we have the profile ID use a profile ID it's this one right here but we also have the actual file so if I open up this file you can see that we have the file name so Antonio jr. and then we have the actual part so this is some information about the file and you can see right here the field name the content type is home field the size you know headers so on and so forth which means that the actual upload from client to server is working which is amazing so now let me actually collapse this and then navigate inside of this service and right here remember that we have to implement all of this logic so now that we have the actual file in our server we can implement it so next let's go ahead and implement this method right here all right so before actually implement this I thought that it would be really great idea if you try and implement all of these steps by yourself so spend about 10 to 20 minutes and implement all of these steps right here so you have everything that you need in order to save the actual file coming from the web app so right here so if I actually go back I still have the breakpoints so you can see right here we have this file right here right so we have the file in our back-end coming from the front end so right here and what we want to do is actually store it inside of the s3 bucket a name called amigos code image upload one two three obviously the bucket name will be different for you but try and implement all of this logic right here so give it a go and what I'm gonna do actually is pretty much just remove this break point and open up debug and then continue and there we go so give it a go implement all of these steps and I'm gonna implement these steps with you next alright let's go ahead and implement all of these steps together now if you had a go I'm going to guarantee you that my implementation will be different than yours because you know we have different ways of implementing things and different ways of thinking so if you achieved the same solution but in a different way that is absolutely fine so the first one so to check whether the image is empty I'm going to say if and then file don't is empty so this is very straightforward so if the file is empty I'm going to throw new illegal State exception so right here you could actually have your custom exceptions but I want to keep it dead simple and throw illegal state exceptions also if you learn more about exceptions check out my video on exceptions which I'm going to leave a link down in the description of this video so right here I'm going to say cannot and then upload empty and then file and then I'm going to actually add the actual size so right here plus and then file dot and then we should have the actual size so right here and then plus and then end that there we go so this is the first implementation now to check whether the actual file is an image I'm going to say if and then arrays dot and then as list and then I'm going to pass few things so let me simply say it contains and then right here I'm going to say file dot and then get and then content type so right here so what I'm gonna do is actually inverse this so I'm gonna say if it doesn't contain I think there is a content and then type so that would be I think from Apache dot and then yes exactly so image dot jpg right here and also I can say content-type oops dot and then P&G content-type dot and then yes there we go so let me actually just add a static import for all of those there we go and this looks much better so now if it doesn't include any of those I'm going to throw an illegal state exception again as I said you could have your own custom exception but for now this will be an illegal State exception but for now let me simply go ahead and delete all of this and simply say file must be an image and there we go so next let's go ahead and implement whether the user exists in our database because we're not using a real database so ie so if I show you the actual database that we have so datastore fake user profile datastore so this is a in-memory database inside of a list so because we're only using a real database we can't issue commands such as you know select from you know table where the ID equals blah right so let's actually go ahead and use some Java streams to filter a particular user based on this ID so let's go ahead and write here so at the very top you see that we have the user profile data access service so what am i doing here is simply saying user profile data access service and let me put this full screen don't and then I'm gonna say get user profiles and then dot and then shrim right here so right here I'm entering the abstraction face so if you learn more about streams check out my website where I've got a full course on streams it's very powerful you should be using it in your code base so right here let me simply add any line the same here and what I'm gonna do is simply say dot and then filter so I'm gonna use the filter function right here we simply have the user profile and then I'm gonna say user profile dot and then get and then profile ID equals and then the actual user profile so basically I'm saying I'm going to go through this list right here and then I'm gonna filter a user profile which the ID is equal to the one coming from the client so this one right here and then I'm going to say dot and then find and then first and then if we don't find anything I'm going to say dot and then or else I'm going to throw a new exception so throw let's actually throw this exception so this will be exception so I'm going to say new illegal State exception and then right here so user in fact let me use a format so string dot format and then equals and then right here I'm going to say user profile and then percent s not found and then pass the actual user profile ID there we go so you can see that this looks really clean and you know streams is really powerful so now what I'm gonna do is actually extract everything into a variable and right here we have the actual profile so I'm gonna say user sir right here so this is the actual user containing all the information that we need so if I open up to user profile you can see that has the actual ID a user name as well as the actual link so there we go so now is implemented this third step now let's actually grab some metadata from the foul if any so right here what I'm gonna do is simply say Matt and this will be a string and then a string and then I'm gonna say meta and then data equals to new and then hash map there we go and now I'm gonna say file dot and then get content type so right here so you can see that we always get the content type so I want to say actually let me actually cut that so I'm gonna cut this and then say metadata dot and then put and then I'm gonna say content and then - and then type and then paste that and the same width so dot and then put and then content - and then length so we know that if we get to this part right here we will have a file right because we are checking whether it's empty or not up above now I'm going to say file dot get and then size right here and obviously this should be a string so I'm going to say string dot value off and then the actual size and there's also now we have the actual metadata that we can pass to our method and finally let's go ahead and pretty much insert the actual file to our destiny bucket so right here so remember that so if I expand this we implemented this file store and the file store has the actual save method so right here let me go back and let's actually inject the private final file and then store and make sure that you implemented one from your package because there are quite a few so import the very first one there we go our two constructor and if I put this on a new line and see everything properly let me go down and now right here I'm going to say file store dot actually not file the file store dot and then safe so the safe will take a couple of things it will take the actual path right so the path will be the actual bucket so what I want to do really is inside of s3 right here so you can see that we have an empty bucket but basically I wanna have a folder per user right and then in each folder for a specific user you can see the list of every single uploaded file for that specific user so basically inside of a bucket you can simply have folders right so we'll have a folder for Antonio and another folder for Janet Jones so the way that we achieve this is by simply so let me actually go ahead and simply say string and then dot format and then I'm going to say that this will take the actual bucket name and then forth slash that will be the actual folder for the actual user profile ID so let me simply say percent and then s and then right here let's go ahead and use our bucket so I'm gonna say bucket and then name dot and remember we have profile image don't and then get the bucket name and right here let's pass the user dot and then get profile ID so there you go so this will be the actual path so this is the path so let me actually pass the past right here and then for the file name the file name will be the actual file name plus a random string so again let me simply use string dot format and then right here I'm going to say the file name will be the actual file name so percent s and then - and then I'll run them you it so we're here simply say file dot and then get name and then let's actually generate a random you it so random you it and there we go so this will be the actual file and then the name and let me actually pass inside of this safe method so file name what do we have next next we have the actual metadata so right here we say optional dot off and then meta data and finally you can see that we have to specify the actual input stream so this is the actual file so this will come from foul dot and then get input stream and obviously this throws an exception so let's actually go ahead and simply surround it with try catch so we're going to not bring this distract race but we're going to throw so I'm going to throw you a legal state exception and then for now let's simply say II so I think we have an error here so this should be percent s so just like that and that went away so there we go so we've managed to implement all of these five steps so if you have any questions on these go ahead and drop me a message but next let's go ahead and see if everything works according our implementation as I said you might have a different implementation and what I have but if you can achieve the exact same thing in a different way that is absolutely fine next let's go ahead and test whether we can upload files to Amazon s3 all right so we have a bunch of logic inside of this method right here and you can go ahead and extract this to a method to make it cleaner and basically or actually that let's actually do it so why not so I'm gonna track this to a method so is a file empty so this I think looks looks much better so right here let's go ahead and say is in an image so right here let's actually go ahead and simply say so I'm going to extract all of this to a method so extract this to a method so get and then user and then profile or and then throw and then enter there we go and then right here let's go ahead and grab everything extract to a method so get actually extract meta and then data there we go and and I think this should be here so now you can see that this looks much cleaner and you can read through easily so now let's go ahead and pretty much just start the application and what we're gonna do is let's go to our front-end and let's try and add this image right here so actually let me change the order right here so it's not confusing so let's actually try and upload an image for Janet Jones so I'm gonna grab the image and then I want to drop right here and let's inspect the actual console and it's big confusing right here so we have file uploaded successfully but we also have a 500 so let's actually see what is happening so if I go to the server so right here file must be an image ok so let's see exactly when wrong so obviously I should have actually printed the actual content type so is image so let's go ahead and print the actual image content or actually content type so file dot and then get content type and if I restart the server and then go back so let's actually upload again and it's a five hundred let me go back and I can see that it's image and then JPEG so I think what is happening is that we have a bug so I'm actually collapse this and this should be dot and then get and then mime type so I think this is what gives us the actual mime type right so that's the actual shrink so let's add the dot and then get mime type again here don't get mime type so obviously you should have tests around this and I you know always add tests if I'm adding stuff like this because it's really important that you test whether your services do works or never you know push stuff to master or to a branch without having tests so if you want to learn about testing go ahead and drop a message and I'll show you how to test all of this so now let's go ahead and refactor or actually restart not refactor and let's clear the console right here now let's go ahead and try and upload so I'm gonna grab the image and then upload and this time you can see that no errors and there we go well done so it means that the file was successfully upload it to s3 so again let me also upload the Antonio jr. so I'm gonna grab the file put it here and just give it a second there we go file uploaded successfully and now let's actually check the s3 bucket so if I go to s3 management console and then refresh and there you go so you can see that we have two folders for each specific user right so this right here 8d so ad was Antonio jr. and then we also have the 38 which is Johnny Jones now if I open up now if I dig into each folder you can see that we have a file right here and in fact the actual file name is incorrect so let me actually go back and check the other one and also it simply says file and then the random view it but in fact this is an image so if I click on this image and then you can see that we have the metadata and right here you can see that this was the metadata that we've added and there we go you successfully managed to upload a file to a bucket inside of Amazon AWS so let's actually go ahead and fix a few things here so what I want to fix right here so basically what I want to do is actually go back to the user profile service and I think right here so where we generate the actual file name so this thing right here so get name I think this should be get and then original file name so that will give us that so in fact let's go ahead and restart the server and let me open up the debug mode let me cancel out of this and let me simply collapse this let me start the server let me go back and let me delete these two folders inside of our bucket so delete there we go and now if I go back to my front-end refresh and then let me actually upload a file from for Janet Chun there we go and the same for Antonio Junior there you go so both successfully if I go to the console refresh you can see that we have the UITs if I click on it and there we go so this makes more sense now you can see the file name is Janet Jones JPEG and then the random string the same for Antonio jr. right here and basically if I upload so let me go back to the app so if I upload the file again that should work and if I blowed it again that should work and if I go back to the console and then open up the folder refresh you can see that we have two files and the reason why I'm doing this is so that you can keep a history for all the profile pictures uploaded for each user so you can see Janet Jones two fouls and the same wait Antonio jr. so there we go you've managed to successfully upload images from your web app to the Amazon AWS s3 bucket and this is really really great so now you can take all of this and pretty much just incorporate it in your apps so next let's go ahead and learn how we're going to be able to download the actual image so basically right here we want to get the image so basically we want to display the uploaded image right here so let's go ahead and do that next alright let's go ahead and learn how we're going to be able to get the image that we've stored inside of Amazon AWS and then retrieve it and show it right here so what I'm going to do first is for Janet Jones I'm gonna grab this Hewitt and then go back to our fake user data store and instead of generating the you it I'm gonna paste at you it there right and this should be actually you it and then from string and then paste to you it because the you which they don't get generated as soon as we restart the server so let this actually be oops not there so let's actually let the UITs be fixed so obviously if you are using a database all of this is is actually solved but we are using an in-memory database and this is what happens when you use an in-memory database right so now if I restart the server this so now if I restart the server so let me actually start server and if I go back and then refresh the you it should be the same so right here you see that they are the same so now what we need to do is so if I open up the user profile service so right here so right here you see that we saved the actual image which is absolutely fine but we haven't updated so right here so we haven't updated this field right here so user profile image link right so this is how we will be able to download the actual images for a specific user basically right here this will always be the latest image that we upload for a particular user profile so if I go back and right here so remember I said and update database user profile image link with s3 image link so we already have this so this is the actual link so path plus the actual file name so this in this will give us the actual link for the image so let's go ahead and after we save the image let's go ahead and simply say user dot and then set so set user profile image link and for now let me simply add the actual file name so I'm going to construct this later when we actually download the image so when we have the method to download the image because I can always reconstruct this so there we go so now we have the filename now let me also teach you something so right here you see that I'm using user and then dot set so the reason why I haven't added a final so private and then final right here as I always do for immutability is because I'm not using a real database and I need to have the ability to set these properties so this is something to keep in mind and also because I'm not updating the actual ID and username so it's actually add a final here and final there and now obviously we can't have these setters so this is much cleaner in fact so there we go so you can see now that this is much better so let's actually restart the server because I want you to see this in action so let's restart the server there we go so now if I restart you can see that nothing has changed but now if I upload as upload a third time so let's upload this image right here there we go so file uploaded successfully now so if I riff fresh this API call remember before the user profile image link was null for in China Jones so now this should be set with so right here if I go to the console so Janet Jones was this one so if i refresh so you can see the latest one is the this one right here in the middle so three ending in three see so let me actually go back now and then refresh you see that now the user profile image link has been updated which means I can now download this and pretty much just show it right here and that's what we're going to do next all right so you can see that we have this link right here now we can simply go to our packet and retrieve the image so make sure not to restart the server because if you restart the server you will lose this link right here and then you'll have to upload the image again but all of this is because I'm using an in-memory database and that's the downside of an in-memory database so if I'm actually implementing this for real I would use a real database and if you want to learn how to connect to a real database with spring book go ahead and check my videos where I teach all of that so now let's go ahead and create an endpoint that will allow us to fetch the image from Amazon s3 bucket so let's go ahead and open up IntelliJ and what I'm going to do is open up the user profile controller so right here so let's go ahead and add a method and right here let's simply say public and then this will return a byte array and let's simply say download actually let me copy this so let me be a bit lazy so let me simply say down so I set it up and then profile image so right here what we need is again the actual path variable so let me put it there and that's all we need so now this will be at and then get and then mapping so the path will almost be the same thing so in fact let me simply put it there or actually I don't need all of that so I think I can just get that and then I put it there and it set off upload this will be down and then load there we go so let me actually expand this so what we're gonna do is simply say user and then profile service dot and let's actually take this same name and then pass the user profile ID right so now let's simply go ahead in return so we're going to return this to the client now let me actually implement this method inside of our service and what we need to do is the following so let's actually go ahead and say that we first need to check whether the user exists right so let me actually grab this method so I like to have all the public's in my section and all the private in my section so what I'm going to do right here is simply so before I return I'm going to say get and then user or or else throw so user profile ID so right here we have the actual user right so this will throw and we will get the actual user so right here now that we have the user we know that we can fetch the actual a profile image so remember right here where we have the actual path so we have the path so let's actually reconstruct the path so right here so we have the path which is the bucket name plus the user dot get profile ID and now we need the actual file name which we have from this user so if I click on it you can see that we have the user profile image link so let's go ahead and simply say file store dot and then download so the download will simply take the full path so the poop so the full path will be string dot and then format and then % partially we think also percent and then s followed by percent and then s so right here all in in fact let's actually say full path here right so full path and then this will be forward slash and then percent in the mess and we don't need of this one right here so let's pass the whole path and right here so let's actually put this on the new line in your line there as well and we need to pass the user don't and then get the actual link there we go so this is the actual full path to the image and we can simply pass it here and finally let's go ahead and simply say return so now let's go ahead and create this method inside of the final story so right here we have the full path and the way that we will download an image from s3 is very simple so let's uh so so let's have a try block because things can go wrong and let's also catch so we're gonna catch the Amazon service exception and then simply say II and I simply throw so right here so failed to download right so now what we need to do is simply say return and then s3 dot and then you can see that we have a method called get and then object so this get object takes two things takes the path and then the actual key so in fact I think that we need to separate the actual path and the key so let me actually say path and then this will be the string key so let's actually pass the path and the actual key let's go back where this is cold and let's actually regret this so we wanted to have that there remove this one so this is the actual path and then we want to have the path so this will be path and right here so we need to do something so we need to say user dot and then get use a profile image link right here so remember if this is present I'm going to say dot and then map so I'm going to map this to a byte array so I'm gonna get the actual link and then this will say file store thought download passing the actual path and then the link so actually let me name this key so this will be the actual key right we get the idea and then dot or and then else so let's so new and then bite and then this will be a byte of 0 right so this looks much cleaner and let me return this so as I said you can go ahead and pretty much just check my website if you want to learn more about streams but this is how we download a file so now inside of the download method so actually I think that we need to so if I remove this so let's actually say s3 dot and then get object passing the path as well as the key so now with this we have the s3 object and now from the object I can say object dot and then get and you can see that we have the content so right here so content which is an input stream so there we go so now that we have the input and stream what we're gonna do is simply say i/o and then utils dot and then to byte array and then pass the input stream just like that and basically now I can simply say return and we have to catch the i/o exception right here and there we go so let me inline this and this should be it so let me actually remove that line and now I think we are in a good position to test whether we can download a file all right so let's implement the logic in our front-end to download the images from our buckets so open up the s code and this will be very straightforward so what we need to do is right here so where we have the actual div so remember we had need to do so what we're gonna do is very simple so simply add curly brackets and then say user profile and then dot user profile image ID so if we have that we will have an image tag so image tag and then the SRC so s our C will be you should guess so this will be almost the same as this one right here actually where's the download so write this one here so let's grab all of this and then put it here inside and instead of upload this will be down and then load and right here we need to have the else block let's actually have no right so we either have an image or we don't have an image so if i refresh that and user profile ID is not defined so obviously so because we need to say user profile so you need to grab with that and say dot user profile ID so if I save this and this is not going to work because it's a 404 and that's because I need to restart my server so let me restart the server there we go and in fact let me actually cancel this stop and then start in debug mode and let me put the breakpoint actually so let's actually walk this through so where we download the image so let's put the breakpoint right here there we go so now if I go ahead and upload let's upload an image again and you see that worked the same for Antonio jr. there we go now if i refresh this and see that we go straight to our back-end and let's and let's walk this through so we actually have a user and then the path so let me show you what the path is so the path is this so then you put this actually let me show you here so this is the path right amigos code image upload one two three and then this is the actual food path so remember it so this is the folder so this is the folder so 84 so right here so let me show you exactly what is that so 84 so if I go back is this folder and then inside of that folder we have the actual so if I open up the user profile so the link so right here ends in 68 so you can see that we have 68 right here so that should download that file now if I go into this method so let me put a breakpoint there so let me continue you can see that I've hit this breakpoint now the key you can see that the key is correct right so 68 and if I step over there you go so now we've managed to download the phone so you see that this is the actual file containing a bunch of information right so you can see the metadata inside and the actual content now if I go ahead and simply continue and let's check the console so you see that no errors so if I go back to our front-end and then you see that we've actually downloaded the actual image Wow you see that we've downloaded both images and basically they are really really big and what we need to do is to resize them so if I open up our front end and what we're gonna do is inside of the app dot CSS so right here let's go ahead and add some CSS so for the images that we have one model is seem to say width of 300 and then let's actually say that height will also be 300 and this would be pixels so turn your pixels pixels and let's say object and then fit and then cover and finally let's go ahead and say border - and then radios so we'll have a border radius of 50 and then percent oops 50% there so now if I save this and let me actually go back and let me actually mute all breakpoints there we go and now if i refresh the application there we go so you can see that this is working nice and in fact let me actually make this 200 so 200 200 save that go to index dot JSON simply save margin and then top and let's add a margin top of 100 pixels so just like that and let's go back and voila so you can see that this is working beautifully now I think we are really close to the end so let me actually show you that if I go to pixels and then simply say girl so let's choose a different picture so I say that now you know she looks like this so download and this was what Janet let me simply say Janet and then let's actually do the same for a boy there we go so let's actually say that this is which picture so let's say that this guy right here so let's say that this guy right here is Antonio so free download Antonio save and you can see that we have the new pictures right here and let me go back to the app and if I now pretty much just change the image so right here I'm gonna drop it and let's do the same for Antonio so let's drop both of these images and you can see that currently we're not refreshing on success but that is something that you can add on your own and expand on this user interface so now if i refresh this you can see that the images did update and basically this is just working so so as I said you can pretty much just add a bunch of functionality to your own application but you can take whatever you've learned in this tutorial to store and download images so right now we are using react but for example if you wanted to store images from your you know iOS app or Android app you could definitely do it right because the API is the same so I think that this is all so right here you can see that we've managed to implement everything that we wanted right so if I make this full screen so you can see right here so we have the client we expose an API and then the service does a bunch of logic and then we store to s3 as well as have the profile in a fake database so obviously you know if I restart this so if I restart the application I will lose the actual images right because so if I go to so if I go to the fake user profile datastore so right here you can see that this is set to no right but you could also you know grab the actual link and put it here but you know if you are doing this for real please do not use this fake user profile data store so if you want to learn more about dependency injection go ahead and check my website my YouTube videos where I cover all of that this is all for now and let's wrap up things all right so thank you so much for sticking with me throughout this course now as you saw saving images it's a really really cool thing that you should be aware of how to do it right because nowadays we are storing lots of information about it users and to be honest we are storing you know nowadays we're sorting fouls you are storing content and you couldn't install videos right you can store anything you want with what we've built because after all we are sending a file as a input stream and then you storing that into the s3 bucket and you can pretty much just or whatever you want so it was a pleasure teaching you if you haven't subscribed to my channel go ahead and subscribe because it will help me to do more videos like this also if you have any questions or suggestions go ahead and message me this is all for now and I'll catch you on the next one you
Info
Channel: Amigoscode
Views: 186,459
Rating: undefined out of 5
Keywords: spring boot tutorial, spring boot security, spring boot java, spring boot rest api, spring boot web application, spring boot application, spring boot angular, spring boot annotations, spring boot api, spring boot aws, spring boot crash course, spring boot crud, react js, reactjs basics, reactjs hooks, reactjs 2020, react js crash course, reactjs projects, reactjs app tutorial, spring boot jpa, quarentine
Id: i-hoSg8iRG0
Channel Id: undefined
Length: 139min 59sec (8399 seconds)
Published: Sat Mar 28 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.