Skip to content

Java Image S3 Upload

How it works

  1. You create a bucket on Amazon S3 and set the CORS for it.
  2. Your code computes the Amazon S3 signature on server side.
  3. The javascript editor is initialized with the imageUploadToS3 option.
  4. When an image is uploaded, it is being sent directly to the S3 bucket without touching your server.

Jump to Complete Example

Create a S3 Bucket

Amazon explains in detail on the URL below how to create a bucket and set a region for it. If you have any troubles with creating it, please contact Amazon for getting it set up.

http://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html

Set CORS on the S3 Bucket

Cross-origin resource sharing (CORS) mainly tells Amazon from which domains to accept requests and what kind of requests. A detailed explanation of how that works can be find in Amazon Documentation.

We recommend to add a configuration like the one below where you would replace the ALLOWED_URL with the URL of the page where you're using the javascript editor.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>ALLOWED_URL</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Compute Signature

In order to get the image uploaded to S3, it is necessary to compute a signature using the AWS access key ID and AWS secret access key and provide it together with the upload request. The rich text editor Java SDK comes with methods to compute the S3 signature using the V4 signing algorithm that works with buckets created on any of the S3 regions.

S3Config config = new S3Config();

// The name of your bucket.
config.bucket = 'bucket-name';

// S3 region. If you are using the default us-east-1, it this can be ignored.
config.region = 'eu-west-1';

// The folder where to upload the images.
config.keyStart = 'uploads';

// File access.
config.acl = 'public-read';

// AWS keys.
config.accessKey = YOUR_AWS_ACCESS_KEY;
config.secretKey = YOUR_AWS_SECRET_KEY;

// Compute the signature.
Map<Object, Object> hash = S3.getHash(config);

Initialize the Javascript editor

To get images uploaded to Amazon S3, the imageUploadToS3 option should be set on initialization. The editor Java SDK computes the hash required for this as the response of the com.froala.editor.S3.getHash method.

<script>
  $.get( "/amazon_hash", {})
  .done(function( data ) {
      $('.selector').froalaEditor({
          imageUploadToS3: data
      })
  });
</script>

Complete Example

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>ALLOWED_URL</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
package com.froala.examples.servlets;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.froala.editor.S3;
import com.froala.editor.s3.S3Config;
import com.google.gson.Gson;

/**
 * Servlet implementation class AmazonHash
 */
@WebServlet("/amazon_hash")
public class AmazonHash extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public AmazonHash() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        Map<Object, Object> hash;
        S3Config config = new S3Config();
        // The name of your bucket.
        config.bucket = 'bucket-name';

        // S3 region. If you are using the default us-east-1, it this can be ignored.
        config.region = 'eu-west-1';

        // The folder where to upload the images.
        config.keyStart = 'uploads';

        // File access.
        config.acl = 'public-read';

        // AWS keys.
        config.accessKey = YOUR_AWS_ACCESS_KEY;
        config.secretKey = YOUR_AWS_SECRET_KEY;

        try {
            // Compute the signature.
            hash = S3.getHash(config);
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }

        String jsonResponseData = new Gson().toJson(hash);
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(jsonResponseData);
    }

}
<script>
  $.get( "/amazon_hash", {})
  .done(function( data ) {
      $('.selector').froalaEditor({
          imageUploadToS3: data
      })
  });
</script>