Created
January 5, 2018 02:43
-
-
Save aaronanderson/ef6d319220d0ff938fa3c1013c4e80de to your computer and use it in GitHub Desktop.
Amazon AWS Java SDK 2.0 DynamoDB utility class to convert between AttributeValue and json-p 1.0 javax.json objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.math.BigDecimal; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import javax.json.Json; | |
import javax.json.JsonArray; | |
import javax.json.JsonArrayBuilder; | |
import javax.json.JsonNumber; | |
import javax.json.JsonObject; | |
import javax.json.JsonObjectBuilder; | |
import javax.json.JsonString; | |
import javax.json.JsonValue; | |
import software.amazon.awssdk.services.dynamodb.model.AttributeValue; | |
public class DynamoDBUtil { | |
public static void addList(String key, JsonObjectBuilder objectBuilder, List<JsonObject> items) { | |
if (!items.isEmpty()) { | |
JsonArrayBuilder builder = Json.createArrayBuilder(); | |
items.forEach(i -> builder.add(i)); | |
objectBuilder.add(key, builder.build()); | |
} | |
} | |
public static JsonArray toJson(List<AttributeValue> attributeValues) { | |
if (attributeValues == null) { | |
return null; | |
} | |
JsonArrayBuilder valueBuilder = Json.createArrayBuilder(); | |
for (AttributeValue a : attributeValues) { | |
add(toJson(a), valueBuilder); | |
} | |
return valueBuilder.build(); | |
} | |
public static JsonObject toJson(Map<String, AttributeValue> attributeValues) { | |
if (attributeValues == null) { | |
return null; | |
} | |
JsonObjectBuilder valueBuilder = Json.createObjectBuilder(); | |
for (Map.Entry<String, AttributeValue> a : attributeValues.entrySet()) { | |
add(a.getKey(), toJson(a.getValue()), valueBuilder); | |
} | |
return valueBuilder.build(); | |
} | |
public static void add(String key, Object value, JsonObjectBuilder object) { | |
if (value instanceof JsonValue) { | |
object.add(key, (JsonValue) value); | |
// with json-p 1.0 can't create JsonString or JsonNumber so simply setting JsonValue not an option. | |
} else if (value instanceof String) { | |
object.add(key, (String) value); | |
} else if (value instanceof BigDecimal) { | |
object.add(key, (BigDecimal) value); | |
} else if (value instanceof Boolean) { | |
object.add(key, (Boolean) value); | |
} else if (value.equals(JsonValue.NULL)) { | |
object.addNull(key); | |
} | |
} | |
public static void add(Object value, JsonArrayBuilder array) { | |
if (value instanceof JsonValue) { | |
array.add((JsonValue) value); | |
} else if (value instanceof String) { | |
array.add((String) value); | |
} else if (value instanceof BigDecimal) { | |
array.add((BigDecimal) value); | |
} else if (value instanceof Boolean) { | |
array.add((Boolean) value); | |
} else if (value.equals(JsonValue.NULL)) { | |
array.addNull(); | |
} | |
} | |
public static Object toJson(AttributeValue attributeValue) { | |
// with json-p 1.1 Json.createValue() can be used. | |
if (attributeValue == null) { | |
return null; | |
} | |
if (attributeValue.s() != null) { | |
return attributeValue.s(); | |
} | |
if (attributeValue.m() != null) { | |
return toJson(attributeValue.m()); | |
} | |
if (attributeValue.l() != null) { | |
return toJson(attributeValue.l()); | |
} | |
if (attributeValue.n() != null) { | |
return new BigDecimal(attributeValue.n()); | |
} | |
if (attributeValue.bool() != null) { | |
// return attributeValue.bool() ? JsonValue.TRUE : JsonValue.FALSE; | |
return attributeValue.bool(); | |
} | |
if (attributeValue.nul() != null && attributeValue.nul()) { | |
return JsonValue.NULL; | |
} | |
/* if (attributeValue.b() != null) { | |
* return Base64.getEncoder().encodeToString(attributeValue.b().array()); | |
* } */ | |
return null; | |
} | |
public static Map<String, AttributeValue> toAttribute(JsonObject jsonObject) { | |
Map<String, AttributeValue> attribute = new HashMap<>(); | |
jsonObject.entrySet().forEach(e -> { | |
attribute.put(e.getKey(), toAttribute(e.getValue())); | |
}); | |
return attribute; | |
} | |
public static List<AttributeValue> toAttribute(JsonArray jsonArray) { | |
List<AttributeValue> attributes = new LinkedList<>(); | |
jsonArray.forEach(e -> { | |
attributes.add(toAttribute(e)); | |
}); | |
return attributes; | |
} | |
public static AttributeValue toAttribute(JsonValue jsonValue) { | |
if (jsonValue == null) { | |
return null; | |
} | |
switch (jsonValue.getValueType()) { | |
case STRING: | |
return AttributeValue.builder().s(((JsonString) jsonValue).getString()).build(); | |
case OBJECT: | |
return AttributeValue.builder().m(toAttribute((JsonObject) jsonValue)).build(); | |
case ARRAY: | |
return AttributeValue.builder().l(toAttribute((JsonArray) jsonValue)).build(); | |
case NUMBER: | |
return AttributeValue.builder().n(((JsonNumber) jsonValue).toString()).build(); | |
case TRUE: | |
return AttributeValue.builder().bool(true).build(); | |
case FALSE: | |
return AttributeValue.builder().bool(false).build(); | |
case NULL: | |
return AttributeValue.builder().nul(true).build(); | |
} | |
return null; | |
} | |
} |
All paths of inquiry on this topic lead back to this gist 👍 so I am posting a link to a Jackson JSON Serializer which may be useful: https://gist.github.com/nickman/991dea808b6f43e7346d6d570f3c9ffe
Hello, the new version DynamoDBUtil.java had a error with the list of string, line 124 - 126:
if (!attributeValue.ss().isEmpty()) {
return attributeValue.ss();
}
But i can solution with this code:
if (!attributeValue.ss().isEmpty()) {
JsonArrayBuilder valueBuilder = Json.createArrayBuilder();
for (String element : attributeValue.ss()) {
valueBuilder.add(element);
}
return valueBuilder.build();
}
Maybe exists a better way, but i dont have more time for think, really thanks for that DynamoDBUtil code.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks! That code has the same problem, though. There's a check for emptiness to distinguish maps and lists, but those are allowed to be empty, contrary to the set types. I found the solution here: aws/aws-sdk-java-v2#865. You have to check for instanceof SdkAutoConstructList/SdkAutoConstructMap instead of isEmpty().