Amazon DynamoDB
Developer Guide (API Version 2012-08-10)

Example: Handling Binary Type Attributes Using the AWS SDK for Java Document API

The following Java code example illustrates handling binary type attributes. The example adds an item to the Reply table. The item includes a binary type attribute (ExtendedMessage) that stores compressed data. The example then retrieves the item and prints all the attribute values. For illustration, the example uses the GZIPOutputStream class to compress a sample stream and assign it to the ExtendedMessage attribute. When the binary attribute is retrieved, it is decompressed using the GZIPInputStream class.


The SDK for Java also provides an object persistence model, allowing you to map your client-side classes to DynamoDB tables. This approach can reduce the amount of code you have to write. For more information, see Java: DynamoDBMapper.

If you followed the Creating Tables and Loading Sample Data section, you should already have created the Reply table. You can also create this tables programmatically. For more information, see Creating Example Tables and Uploading Data Using the AWS SDK for Java.

For step-by-step instructions to test the following sample, see Java Code Samples.

// Copyright 2012-2015, Inc. or its affiliates. All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
package com.amazonaws.codesamples.document;

import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.amazonaws.auth.profile.ProfileCredentialsProvider;

public class DocumentAPIItemBinaryExample {
    static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(
            new ProfileCredentialsProvider()));
    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    public static void main(String[] args) throws IOException {
        try {
            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";
            String replyDateTime = dateFormatter.format(new Date());
            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);
            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);
            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);

    public static void createItem(String threadId, String replyDateTime) throws IOException {
        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";
        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());
        table.putItem(new Item()
            .withPrimaryKey("Id", threadId)
            .withString("ReplyDateTime", replyDateTime)
            .withString("Message", "Long message follows")
            .withBinary("ExtendedMessage", compressedMessage)
            .withString("PostedBy", "User A"));
    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {
        Table table = dynamoDB.getTable(tableName);
        GetItemSpec spec = new GetItemSpec()
            .withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)

        Item item = table.getItem(spec);
     // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));
        System.out.println("Reply message:\n"
            + " Id: " + item.getString("Id") + "\n" 
            + " ReplyDateTime: " + item.getString("ReplyDateTime") + "\n" 
            + " PostedBy: " + item.getString("PostedBy") + "\n"
            + " Message: " + item.getString("Message") + "\n"
            + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    public static void deleteItem(String threadId, String replyDateTime) {
        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        byte[] compressedBytes = baos.toByteArray();
        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling ByteBuffer.wrap(compressedBytes);  
        // However, the longer form below shows the importance of resetting the position of the buffer 
        // back to the beginning of the buffer if you are writing bytes directly to it, since the SDK 
        // will consider only the bytes after the current position when sending data to DynamoDB.  
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer to the beginning
        return buffer;
    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);
        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length =, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        String result = new String(baos.toByteArray(), "UTF-8");

        return result;