hi i'm cameron mckenzie at cameron mcnz on twitter and i wanted to show you how to create
a spring boot file upload the easiest possible way you can with just one java file one html file
a little bit of html5 sprinkled in there and i think you'll be amazed
at how easy it is to create a spring boot file uploader in 2020
so if we want to spring boot file uploader the first thing we need to do is create a spring boot
project and i'll call the spring boot uploader that looks good comm mcnz spring i'm liking all
of these settings that i see so far now what do i have to include here well i have to include web
if you don't have spring web this will not work so include spring web i'm also going to need what
else i think i might include dime leaf although i don't think i'm actually going to do anything
with that so okay maybe you don't need that but i do need the data tools i always like to have
the spring boot dev tools they were nice enough to put them in there for me so i'm nice enough
to use them now as the project starts up i'm going to open this up the first thing that i
need is i need a component on the server to handle the file when it's uploaded i can either create
the web page first or i can create the server side component first but i'm a server side guy
so i'm going to create that server side component i'm going to call it spring file upload controller
sounds like a good name to me i'll click finish there and just using the word controller there
doesn't make it a controller so i've actually got to add a little annotation to the top of that code
there we go at controller control shift o to bring in the imports and all of a sudden my
little error messages go away now notice there is another file created here spring boot creates this
automatically so i'm not going to talk too much about that file there other than to say
it has to exist but if it doesn't exist and you created a springboot project then you did
something seriously wrong the spring file upload controller is the only java class that i'm going
to concern myself with now i do want to put a little get mapping in here that's going to call
the index.html page if someone goes localhost 8080 index that'll fi that'll bring up the index.html
page i'm going to create in just a moment in fact it looks like i'm not going to create a page
called index.html looks like i'm going to call create a page called uploader.html but it's all
good either way i do have a little error message there so i'll organize my imports and get on with
the real coding this is just i mean that's that's nothing interesting that's boring right there
what is interesting is this method here watch this bang uh public response entity handle
file upload request param file mark multi-part file everything that's important in this class
is going on in here i need a control shift o to just get those imports ready oh no there's still
a white x there if anybody said that's a red x they need to get their eyes checked there's a
white x i don't have a return yet i'm returning a response entity i'm going to make this ajax based
i don't like doing a lot of heavy control in my controllers i'd rather make things ajax based
so here all i'm going to send to the client is a response entity basically a status code so if it's
good it's 400 if it's bad it's 500. that's all i'm going to send back to the client that's all
the client needs to know from the server did you upload the file successfully or not don't bother
me with crazy html and stuff the the web designers can can figure out the response they just need to
know whether things went up well or not so that's why i'm returning the response entity here the
method name is handle file upload but look at this request parameter file multi-part file
what is getting handled and uploaded to the server here is a file and it's a special multi-part file
basically when files are sent across the network from a browser browser they're chunked and they're
put into different parts and they're sent across a server and the server reassembles them and creates
a file from all of those different parts so that's the object that's passed in here and notice that
that object was stuffed into the user's request with the name file we'll see that word file come
up again when we look at the html code but that is the the guts of or at least that's the method
declaration there now that will be called with a post mapping and it'll be localhost 8080 upload
to call it so i need that post mapping right there i'll do control shift o to get rid of the import
errors again i just need to do a return here to get rid of that one so i'm not worried about that
now this file if somebody uploads a file and it's the file name is cali selfie.jpg i want to save
it locally into my upload folder with the name cali selfie.jpg you can see there's the upload
folder right there it's got nothing in it there it is nothing at all in this upload folder but
i want to populate that with all sorts of files but as i said if somebody sends a file named kali
selfie.jpg i want to save it to that folder as kaliselfie.jpg so i need to get the name
of the file as it was served up that's this method here get the file's original name and then all i
have to do is take this file and transfer it to the uploads folder c upload using that file
name so save this file to that upload folder and save it well as a file so this basically takes the
file that's been passed in it creates a new file on the the file system and then shoves that file
into that new file location that's been created now this is persnickety it can throw an exception
so i need to surround this with a try catch block now they're showing off there by catching
all of these different exceptions all i want to do is catch the basic exception e and i
don't want to throw a stack trace that seems rather petulant if you ask me the only thing i
want to do if there's an error is send them a 500 internal server error code and that's how i do it
notice this method returns response entities well spring gives us all of these great methods
for creating these response entities with error codes in them that's the 500 one right there so
that's what happens if this fails what happens if this is okay well if everything is okay well then
why don't i just tell the client that everything is okay so i send the response entity that's
marked okay sends a 200 code back to the client if you want to get technical with a message that says
the file was uploaded successfully now the tool doesn't know that it's in the file is in the i
i owe everybody so i'm surprised it doesn't know that maybe i don't know the jdk anything so i'm
going to organize my imports here right there imports are organized with file i o
i click ctrl s i'm now returning some things from these methods so bob is your uncle everything is
going to work here okay so that's a server side component so notice that the method is called
upload and we look for something called file in the request which should be a multi-part file
okay well to work this all out i need to now create an html form on the client side that'll be
in the templates folder i'll call it uploader.html and that has to map to that return there of the
slash index method so i'll create that basic file in the templates folder and what has to go in here
well first of all we'll kick it off with some very boring html and then we'll terminate it
with some very boring html as well that's just all the static stuff that you need to
set up a page now look at this this is super cool this is html5 stuff this is something special
an input field of type file it's not type submit not type input not type text area not type text
field type file with this html5 element this will provide for a file selector to appear on an html
page where people can fi find things on their local system and then with that after they've
found the file they want to upload we put a button on the page we link it to the upload file method
which hasn't been coded yet and then this will trigger an uploading of the file to the server
through ajax which is really cool remember we're not going to do jquery or anything silly like that
it's going to be pure javascript when i do this so it'll work on any browser
but that's all we need there now by the way you might wrap that in a form that's another way
approach of doing this so if you wanted to put this into a form you could do that you have to
specify the encryption type as multi-part but i like doing things with ajax and here's how
this ajax is going to work and i'm going to just copy and paste this into the page here
basically we're going to do an asynchronous upload so that method's called upload file
that's what's referenced right here we're going to create a javascript form data object and form
data objects are used to pass data to the server and what do we want to make part of
that form data object we want to make that file that's been uploaded notice input id
and name is file upload there so what we're going to do is we're going to take that form data object
we're going to append a file to it and we're going to shove it into the request scope with the name
file now notice that name file that maps right back here to the request parameter file these two
things have to line up if they don't line up then they don't line up which means your code's not
going to work also notice we do fetch to slash upload where slash upload slash upload is the
name of the post mapping so we're calling that url that we specified the previous page we're calling
it with a post invocation we're passing the form data which has the file in it and then we're going
to wait for a status code of 200 and if we get that status code the client is going to send
is going to send a message that says hey file uploaded successfully what happens if
we don't get a 200 message well that is the else block and that's a corner case and that's all
that other stuff and i'm not going to make this tutorial 50 minutes to show you how to write an
else block this is the happy path and for this tutorial i'm going to deal with the happy path
but yeah you might want to deal with it failing as well and send a response that says hey it failed
but you know what that's it that is the code you know it's one two three four
five lines of code in here i don't know if i can even count those catch blocks as code
a little method there just to call and that return uploader just calls this method here
okay and then we've got one two three four you know i i mean this couldn't get easier and this is
all ajax file upload stuff like this is stuff that uh used to be impossible to code 10 years ago now
it's so easy so i'm going to run this application that's all i need this application should run and
i can now do two things i can take a look at my upload folder so there's my upload folder and i
can bring over the application there's the spring boot application right there localhost 8080 index
and i'm going to choose a file and there's that cali selfie she's always smiling i'll click open
i'll press the upload button it says the file was uploaded successfully and there we go boom from
the browser to the server i can do this all day i can take a picture of my favorite car upload it
there boom it's uploaded i can go and i can take a picture of my book pickering is springfield and
upload it and boom it is done and that is html on the client an ajax based call and it's going to a
spring boot spring mvc controller on the server and it is taking that file and saving it locally
to that upload folder and there you go that's all there is to doing ajax based pure javascript
no jquery spring boot html5 file uploader involve it and include it in all of your applications
and there you go that's how easy it is to create a spring boot file uploader now if you enjoyed
that tutorial head over to theserverside.com i'm the editor-in-chief over there we got lots
of great tutorials on spring enterprise java devops you name it if you're interested in my
personal antics you can follow me on twitter at cameronmcnz and subscribe on youtube