Search code examples
jakarta-eefile-uploadamazon-web-servicesuploadamazon-s3

Need to upload file on S3 in Java


I have started working on AWS recently. I am currently working on developing upload functionality to S3 storage.

As per my understanding there could be 2 ways to upload a file to S3:-

  1. Client's file gets uploaded to my server and i upload this file to S3 server using my credentials. [i will also able to hide this from client as i will not be showing the upload details.]

  2. Upload directly to S3

I was able to implement the first approach using simple upload api , but i want to skip the "write uploaded file to server disk" part and stream the content directly to S3 storage, while saving the upload details in my database. I also want to achieve the abstraction of AWS details. How do i do it ?? Please help. Thanks in advance


Solution

  • I am using using byte stream array to write file data to S3 object.

    Code for servlet which is receiving uploaded file:-

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    import com.src.code.s3.S3FileUploader;
    
    public class FileUploadHandler extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            PrintWriter out = response.getWriter();
    
            try{
                List<FileItem> multipartfiledata = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
    
                //upload to S3
                S3FileUploader s3 = new S3FileUploader();
                String result = s3.fileUploader(multipartfiledata);
    
                out.print(result);
            } catch(Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
    

    Code which is uploading this data as AWS object:-

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;
    
    import org.apache.commons.fileupload.FileItem;
    
    import com.amazonaws.AmazonClientException;
    import com.amazonaws.AmazonServiceException;
    import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
    import com.amazonaws.services.s3.AmazonS3;
    import com.amazonaws.services.s3.AmazonS3Client;
    import com.amazonaws.services.s3.model.ObjectMetadata;
    import com.amazonaws.services.s3.model.PutObjectRequest;
    import com.amazonaws.services.s3.model.S3Object;
    
    public class S3FileUploader {
    
    
        private static String bucketName     = "***NAME OF YOUR BUCKET***";
        private static String keyName        = "Object-"+UUID.randomUUID();
    
        public String fileUploader(List<FileItem> fileData) throws IOException {
            AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
            String result = "Upload unsuccessfull because ";
            try {
    
                S3Object s3Object = new S3Object();
    
                ObjectMetadata omd = new ObjectMetadata();
                omd.setContentType(fileData.get(0).getContentType());
                omd.setContentLength(fileData.get(0).getSize());
                omd.setHeader("filename", fileData.get(0).getName());
    
                ByteArrayInputStream bis = new ByteArrayInputStream(fileData.get(0).get());
    
                s3Object.setObjectContent(bis);
                s3.putObject(new PutObjectRequest(bucketName, keyName, bis, omd));
                s3Object.close();
    
                result = "Uploaded Successfully.";
            } catch (AmazonServiceException ase) {
               System.out.println("Caught an AmazonServiceException, which means your request made it to Amazon S3, but was "
                    + "rejected with an error response for some reason.");
    
               System.out.println("Error Message:    " + ase.getMessage());
               System.out.println("HTTP Status Code: " + ase.getStatusCode());
               System.out.println("AWS Error Code:   " + ase.getErrorCode());
               System.out.println("Error Type:       " + ase.getErrorType());
               System.out.println("Request ID:       " + ase.getRequestId());
    
               result = result + ase.getMessage();
            } catch (AmazonClientException ace) {
               System.out.println("Caught an AmazonClientException, which means the client encountered an internal error while "
                    + "trying to communicate with S3, such as not being able to access the network.");
    
               result = result + ace.getMessage();
             }catch (Exception e) {
                 result = result + e.getMessage();
           }
    
            return result;
        }
    }
    

    Note :- I am using aws properties file for credentials.

    Hope this helps.