Skip to content Skip to sidebar Skip to footer

Java Code to Create a S3 Bucket and Upload a File to It

Tutorials / Server Tutorials / Uploading Files


Uploading Files

tutorial java server file-upload


  • HTML
  • Restricting Files
  • File Hosting
  • AWS S3
  • Homework

At present we know how to go user input using HTML forms, and we know how to store that data in a database. We can and then utilise that data to return HTML from a servlet or JSP file.

But so far, all of our user input has been text-based. We've seen stuff like text fields, text areas, dropdown boxes, and checkboxes. But we haven't seen file uploads yet.

That's because file uploading requires slightly more complicated lawmaking than treatment basic text input. This tutorial goes through what nosotros need to practise to handle file uploads.

HTML

Let's first with what the user interacts with: first, we have to create an HTML form that contains a file input.

                          <!DOCTYPE html>              <html>              <head>              <title>File Upload Example</title>              </caput>              <body>              <form              action=              "/upload"              method=              "Mail service"              enctype=              "multipart/course-data"              >              <p>What'due south your proper name?</p>              <input              type=              "text"              proper name=              "name"              value=              "Ada"              >              <p>What file exercise y'all want to upload?</p>              <input              type=              "file"              name=              "fileToUpload"              >              <br/><br/>              <input              blazon=              "submit"              value=              "Submit"              >              </class>              </body>              </html>                      

This HTML page contains a form. Notice the enctype="multipart/class-information" attribute and the <input type="file" proper noun="fileToUpload"> chemical element. This allows a user to select a file for uploading. This won't practise annihilation yet, becuase we oasis't created the server part yet! Let's do that now:

                          import              coffee.io.File              ;              import              coffee.io.IOException              ;              import              java.io.InputStream              ;              import              java.nio.file.Files              ;              import              java.nio.file.StandardCopyOption              ;              import              javax.servlet.ServletException              ;              import              javax.servlet.http.HttpServlet              ;              import              javax.servlet.http.HttpServletRequest              ;              import              javax.servlet.http.HttpServletResponse              ;              import              javax.servlet.http.Part              ;              public              form              FileUploadServlet              extends              HttpServlet              {              @Override              public              void              doPost              (              HttpServletRequest              request              ,              HttpServletResponse              response              )              throws              IOException              ,              ServletException              {              //get the file chosen by the user              Part              filePart              =              asking              .              getPart              (              "fileToUpload"              );              //get the InputStream to store the file somewhere              InputStream              fileInputStream              =              filePart              .              getInputStream              ();              //for example, y'all can copy the uploaded file to the server              //annotation that you probably don't want to practise this in real life!              //upload it to a file host like S3 or GCS instead              File              fileToSave              =              new              File              (              "WebContent/uploaded-files/"              +              filePart              .              getSubmittedFileName              ());              Files              .              copy              (              fileInputStream              ,              fileToSave              .              toPath              (),              StandardCopyOption              .              REPLACE_EXISTING              );              //become the URL of the uploaded file              Cord              fileUrl              =              "http://localhost:8080/uploaded-files/"              +              filePart              .              getSubmittedFileName              ();              //Y'all can get other course data too              String              proper name              =              request              .              getParameter              (              "proper noun"              );              //create output HTML that uses the                            response              .              getOutputStream              ().              println              (              "<p>Thank you "              +              name              +              "! Here's a link to your uploaded file:</p>"              );              response              .              getOutputStream              ().              println              (              "<p><a href=\""              +              fileUrl              +              "\">"              +              fileUrl              +              "</a></p>"              );              response              .              getOutputStream              ().              println              (              "<p>Upload another file <a href=\"http://localhost:8080/alphabetize.html\">hither</a>.</p>"              );              }              }                      

This servlet class contains the doPost() that will burn when the HTML form is submitted. First it gets the uploaded file in a Part object, and and so gets an InputStream from that Part. From here we could use the InputStream to shop the file wherever we wanted, only for now nosotros simply shop it to the WebContent/uploaded-files folder, inside our spider web app directory. That stores the file under the WebContent directory, which means nosotros tin can apply a URL to point to the file! The code uses that fact to output HTML that contains a link to the file that was just uploaded.

Finally, we need a web.xml file that maps the /upload URL to this servlet:

                          <web-app              xmlns=              "http://xmlns.jcp.org/xml/ns/javaee"              xmlns:xsi=              "http://world wide web.w3.org/2001/XMLSchema-instance"              xsi:schemaLocation=              "http://xmlns.jcp.org/xml/ns/javaee 		http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"              version=              "iii.1"              >              <servlet>              <servlet-proper name>FileUploadServlet</servlet-name>              <servlet-class>FileUploadServlet</servlet-class>              <multipart-config              />              </servlet>              <servlet-mapping>              <servlet-proper name>FileUploadServlet</servlet-proper name>              <url-design>/upload</url-design>              </servlet-mapping>              </spider web-app>                      

The merely new matter here is the <multipart-config /> tag. This enables the default configuration for file uploads, but you lot tin likewise use this to customize stuff similar maximum file size and whether uploaded files are stored in memory or in a temporary file.

Run this web app and navigate to http://localhost:8080/index.html to see our upload page:

upload page

And then click the Choose File button to open up up a dialog that allows you to select a file from your hard drive, and then click the Submit button to upload that file to the server. You should then see a link to the file in your server:

uploaded file link

Depending on the type of file your uploaded, clicking the link volition either display the contents of the file in the browser, or download the file. You lot tin also right-click the link to download information technology, just like any other link to a file on the cyberspace.

Restricting Files

One common thing you'll probably want to practice is restrict what types of files a user tin upload. For example, maybe you only desire users to upload epitome files, just non .zippo or .exe files.

You can use the have attribute on the HTML grade to just allow images (more info on that approach here), but similar we discussed before, hackers can easily get effectually client-side restrictions, so we have to do some server-side validation anyway.

Here's a simple modification to our servlet form that only allows users to upload files that end with .jpg or .png:

                          import              java.io.File              ;              import              coffee.io.IOException              ;              import              java.io.InputStream              ;              import              java.nio.file.Files              ;              import              java.nio.file.StandardCopyOption              ;              import              javax.servlet.ServletException              ;              import              javax.servlet.http.HttpServlet              ;              import              javax.servlet.http.HttpServletRequest              ;              import              javax.servlet.http.HttpServletResponse              ;              import              javax.servlet.http.Office              ;              public              course              FileUploadServlet              extends              HttpServlet              {              @Override              public              void              doPost              (              HttpServletRequest              asking              ,              HttpServletResponse              response              )              throws              IOException              ,              ServletException              {              //get the file chosen by the user              Part              filePart              =              request              .              getPart              (              "fileToUpload"              );              if              (              filePart              .              getSubmittedFileName              ().              endsWith              (              ".jpg"              )              ||              filePart              .              getSubmittedFileName              ().              endsWith              (              ".png"              )){              InputStream              fileInputStream              =              filePart              .              getInputStream              ();              File              fileToSave              =              new              File              (              "WebContent/uploaded-files/"              +              filePart              .              getSubmittedFileName              ());              Files              .              copy              (              fileInputStream              ,              fileToSave              .              toPath              (),              StandardCopyOption              .              REPLACE_EXISTING              );              String              fileUrl              =              "http://localhost:8080/uploaded-files/"              +              filePart              .              getSubmittedFileName              ();              Cord              name              =              request              .              getParameter              (              "proper name"              );              response              .              getOutputStream              ().              println              (              "<p>Thank you "              +              name              +              "! Hither'southward the image you uploaded:</p>"              );              response              .              getOutputStream              ().              println              (              "<img src=\""              +              fileUrl              +              "\" />"              );              response              .              getOutputStream              ().              println              (              "<p>Upload another paradigm <a href=\"http://localhost:8080/index.html\">hither</a>.</p>"              );              }              else              {              //the file was non a JPG or PNG              response              .              getOutputStream              ().              println              (              "<p>Please but upload JPG or PNG files.</p>"              );              response              .              getOutputStream              ().              println              (              "<p>Upload another file <a href=\"http://localhost:8080/index.html\">hither</a>.</p>"              );              }              }              }                      

This lawmaking now checks whether the original name of the file ended with .jpg or .png, and if so, it goes through with the upload and creates HTML that contains an <img> tag that points to the URL of the uploaded image file:

uploaded image file

If the user tries to upload a file that ends with something other than .jpg or .png, then they become an error.

Notation that this but checks the filename of the file, not its actual content. Then we're still not stopping a user from, for example, creating a .txt file, renaming it to be a .jpg file, then uploading that. If we want to prevent cases like that, and then we accept to examine the contents of the uploaded file to brand certain information technology contains an immune type. Run into here for a discussion on this arroyo, but basically: find a library that does this for y'all!

File Hosting

The higher up examples store the uploaded file straight in the server directory, which is a bad idea for a few reasons. First, all of the files will be deleted whenever we make a change to our code and redeploy the server. And if we're using a server host like Elastic Beanstalk or App Engine, nosotros might not even be allowed to shop files on our server, which are usually supposed to be as lightweight as possible.

Instead of storing the files on the server or in the web app directory, in real life we probably desire to apply a file hosting provider. Using a file hosting provider allows us to store all of our files separately from the server running our code. When the user uploads a file, nosotros get that file in retentivity on our server, and we and so upload it to the file host. The file host and so gives us a URL for the file that nosotros tin can use in our HTML.

Note that information technology'southward too possible to store your files straight in a database, but that's generally non a smashing idea. Instead, the general arroyo is to shop the file itself in a file hosting provider, and then shop the URL of that file in a database.

AWS S3

Amazon Elementary Storage Service (aka AWS S3) is a file hosting service offered by Amazon. It lets you store your files in Amazon's deject, and it offers a Java library that makes uploading to S3 pretty like shooting fish in a barrel.

Step 1: Create an S3 bucket.

S3 uses the idea of buckets, which are a petty fleck like directories. Y'all tin can organize your files into different buckets, and buckets tin contain subdirectories that then contain files. Login to the AWS S3 console and then click the Create saucepan push button. Give your saucepan whatever proper name you want (I'g calling mine my-uploaded-files for now.)

Click the Next button twice to set the permissions on the bucket. Under Manage public permissions, select Grant public read admission to this bucket. You'll go a warning proverb that this will allow anybody to view the files in this bucket, and that's exactly what we want! Note that you tin also employ S3 to create a private bucket for storing individual files, merely for at present we're just going to create a public bucket that anybody on the internet tin can view. That way we tin can employ URLs that point to these files!

Click Adjacent again and then click Create bucket to create your bucket.

Footstep two: Get your AWS credentials.

To interact with our S3 bucket through code, we need to get some credentials and so we tin prove it'due south united states of america uploading files to our bucket. In that location are a agglomeration of ways to do this, but I'll walk through the simplest approach here. You might want to come back to this later and read through your options and implement something a little flake more complicated, merely for now let's just get something that works.

From the S3 console, click your name in the upper-right corner, and then click My Security Credentials. Click the Admission Keys department, and then click the Create New Admission Central button. In the dialog that pops up, click the Show Access Key link. This displays an Access Key ID and a Clandestine Access Key, which is basically a username and password for your AWS account. Copy these downwards, considering y'all'll need them in a minute!

Step 3: Download the AWS S3 Java library.

Nosotros demand this and then we can write Java lawmaking that uploads files to our AWS S3 saucepan. Go to the AWS Java SDK page and and then click the AWS SDK for Java push in the Downloads section in the upper-correct of this page. That downloads a .zip file, which you tin unzip anywhere. (I'll put mine on my desktop for now.)

This directory contains a aws-coffee-sdk.jar file in the lib folder, and a agglomeration of other .jar files in the third_party binder.

Pace 4: Copy those library jars into the lib folder of your web app directory.

The aws-java-sdk.jar file contains the master AWS Java library. But that library was built using a bunch of other libraries, so we need to copy them from the third_party folder. For the code we're going to write, we need these .jar files:

  • aws-java-sdk.jar
  • eatables-logging.jar
  • httpclient.jar
  • httpcore.jar
  • jackson-annotations.jar
  • jackson-core.jar
  • jackson-databind.jar
  • joda-time.jar

If you're using Eclipse, you lot'll besides want to add together them to your project's build path. If y'all're using the command line, you'll accept to add them to your classpath argument.

Pace v: Write code that uploads a file to S3.

Now that nosotros take those library .jar files, we can write code using the classes in them. These classes let us to write code that uploads a file to S3. Here'due south what our servlet class looks like using S3:

                          import              java.io.IOException              ;              import              coffee.io.InputStream              ;              import              javax.servlet.ServletException              ;              import              javax.servlet.http.HttpServlet              ;              import              javax.servlet.http.HttpServletRequest              ;              import              javax.servlet.http.HttpServletResponse              ;              import              javax.servlet.http.Role              ;              import              com.amazonaws.auth.AWSStaticCredentialsProvider              ;              import              com.amazonaws.auth.BasicAWSCredentials              ;              import              com.amazonaws.services.s3.AmazonS3              ;              import              com.amazonaws.services.s3.AmazonS3ClientBuilder              ;              import              com.amazonaws.services.s3.model.CannedAccessControlList              ;              import              com.amazonaws.services.s3.model.ObjectMetadata              ;              import              com.amazonaws.services.s3.model.PutObjectRequest              ;              public              class              FileUploadServlet              extends              HttpServlet              {              @Override              public              void              doPost              (              HttpServletRequest              asking              ,              HttpServletResponse              response              )              throws              IOException              ,              ServletException              {              //go the file chosen by the user              Part              filePart              =              request              .              getPart              (              "fileToUpload"              );              String              fileName              =              filePart              .              getSubmittedFileName              ();              if              (              fileName              .              endsWith              (              ".jpg"              )              ||              fileName              .              endsWith              (              ".png"              )){              InputStream              fileInputStream              =              filePart              .              getInputStream              ();              String              accessKeyId              =              "YOUR_ACCESS_KEY_ID"              ;              String              secretAccessKey              =              "YOUR_SECRET_ACCESS_KEY"              ;              String              region              =              "YOUR_BUCKET REGION"              ;              String              bucketName              =              "YOUR_BUCKET_NAME"              ;              String              subdirectory              =              "images/"              ;              //AWS Access Key ID and Hush-hush Admission Key              BasicAWSCredentials              awsCreds              =              new              BasicAWSCredentials              (              accessKeyId              ,              secretAccessKey              );              //This class connects to AWS S3 for us              AmazonS3              s3client              =              AmazonS3ClientBuilder              .              standard              ().              withRegion              (              region              )              .              withCredentials              (              new              AWSStaticCredentialsProvider              (              awsCreds              )).              build              ();              //Specify the file's size              ObjectMetadata              metadata              =              new              ObjectMetadata              ();              metadata              .              setContentLength              (              filePart              .              getSize              ());              //Create the upload request, giving it a bucket name, subdirectory, filename, input stream, and metadata              PutObjectRequest              uploadRequest              =              new              PutObjectRequest              (              bucketName              ,              subdirectory              +              fileName              ,              fileInputStream              ,              metadata              );              //Make it public and then we can use it equally a public URL on the net              uploadRequest              .              setCannedAcl              (              CannedAccessControlList              .              PublicRead              );              //Upload the file. This can take a while for big files!              s3client              .              putObject              (              uploadRequest              );              //Create a URL using the bucket, subdirectory, and file name              String              fileUrl              =              "http://s3.amazonaws.com/"              +              bucketName              +              "/"              +              subdirectory              +              "/"              +              fileName              ;              //We can still get other data from the form              Cord              proper noun              =              request              .              getParameter              (              "name"              );              response              .              getOutputStream              ().              println              (              "<p>Thanks "              +              name              +              "! Hither's the epitome you uploaded:</p>"              );              response              .              getOutputStream              ().              println              (              "<img src=\""              +              fileUrl              +              "\" />"              );              response              .              getOutputStream              ().              println              (              "<p>Upload another image <a href=\"http://localhost:8080/index.html\">hither</a>.</p>"              );              }              else              {              //the file was non a JPG or PNG              response              .              getOutputStream              ().              println              (              "<p>Please merely upload JPG or PNG files.</p>"              );              response              .              getOutputStream              ().              println              (              "<p>Upload another file <a href=\"http://localhost:8080/index.html\">here</a>.</p>"              );              }              }              }                      

This code uploads a file to our S3 bucket, and then creates a URL that points to the file we just uploaded. Nosotros can use that URL in our HTML, or nosotros could store it in a database. Simply note that we're no longer storing the file on our server! Try running this web app, uploading a file, and then viewing your bucket in the S3 panel. You'll meet the file has been uploaded to your bucket.

This shows the basics of S3, only in that location are a ton of other things you can practise. Here are a couple things worth checking out:

  • Note that you should never save your credentials into a public repository! Instead, y'all can use a properties file to store your credentials, and and then load that properties file from the code. As long as y'all don't store the properties file in your repo, you're okay. More than info here.
  • Uploads of large files can take a long time. You can get progress info and show something similar a progress bar while the file uploads.
  • Yous can use a custom URL for your S3 bucket by pointing a subdomain of your own domain (for example, s3.example.com) to your bucket's URL.

This tutorial is meant to bear witness you the basics. Y'all now know enough to get-go your own investigating! Bank check out the AWS Java SDK developer guide for a ton more than info.

Homework

  • Add the ability to upload profile pictures to your web app.

Comments and Questions

Happy Coding is a community of folks just like you learning near coding.
Do you have a comment or question? Post it here!

evenwiging.blogspot.com

Source: https://happycoding.io/tutorials/java-server/uploading-files

Postar um comentário for "Java Code to Create a S3 Bucket and Upload a File to It"