在 AWS Java SDK 2.x 中将 DynamoDB Map<String, AttributeValue> 解组为文档样式 JSON

Ale*_*x R 10 amazon-dynamodb aws-sdk aws-java-sdk-2.x aws-java-sdk-dynamodb

使用 Java 将 DynamoDB JSON 转换为标准 JSON问题的答案将于 2022 年过时。

问题是这两个导入都不再起作用:

import com.amazonaws.services.dynamodbv2.document.internal.InternalUtils;

import com.amazonaws.services.dynamodbv2.document.ItemUtils;

会发生什么:导入失败。

您还可以在文档中进行验证,此处:https://sdk.amazonaws.com/java/api/latest/index.html ?software/amazon/awssdk/services/dynamodb/package-summary.html

问题是,在 SDK 2.x 中用什么类来替代这两个类呢?

Ale*_*x R 1

根据上面的评论,目前没有通过 AWS SDK V2 的解决方案。

以下代码可在直接使用 DynamoDB API 时将值转换为可用的 JSON:

private Object unwrapAttributeValue(AttributeValue av) {
    if (av.isNULL() != null && av.isNULL())
        return null;
    if (av.getM() != null)
        return unmarshall(av.getM());
    if (av.getL() != null)
        return av.getL().stream().map(this::unwrapAttributeValue)
                .collect(Collectors.toList());
    return Stream
            .<Function<AttributeValue, Object>>of(AttributeValue::getS,
                    AttributeValue::getN, AttributeValue::getBOOL,
                    AttributeValue::getNS, AttributeValue::getSS,
                    AttributeValue::getB, AttributeValue::getBS)
            .map(f -> f.apply(av)).filter(Objects::nonNull).findFirst()
            .orElseThrow();
}
public Map<String, Object> unmarshall(Map<String, AttributeValue> in) {
    Map<String, Object> out = new HashMap<>();
    for (Entry<String, AttributeValue> e : in.entrySet()) {
        Object uav = unwrapAttributeValue(e.getValue());
        if (uav != null)
            out.put(e.getKey(), uav);
    }
    return out;
}
Run Code Online (Sandbox Code Playgroud)

然后可以将结果Map<String, Object>提供给 Jackson 进行进一步处理,就像普通的 json 数据一样。

另一个用例

以下方法适用于在通过 Jackson 解析 DynamoDB JSON 后转换 DynamoDB JSON,而无需通过 DynamoDB API,例如在使用从日志或 S3 导出检索的 JSON 文件进行单元测试期间:

public static JsonNode unmarshall(JsonNode node) {
    String type = node.fieldNames().next();
    switch(type) {
        case "S":
        case "N":
        case "BOOL":
        case "SS":
        case "NS":
            return node.get(type);
        case "NULL":
            return null;
        case "L":
            ArrayNode arr = JsonNodeFactory.instance.arrayNode();
            node.withArray(type).forEach(item -> {
                arr.add(unmarshall(item));
            });
            return arr;
        case "M":
            ObjectNode out = JsonNodeFactory.instance.objectNode();
            node.get(type).fieldNames().forEachRemaining(key -> {
                final JsonNode value = unmarshall(node.get(type).get(key));
                out.set(key, value);
            });
            return out;
        default:
            throw new IllegalArgumentException(type);
    }
}
Run Code Online (Sandbox Code Playgroud)