AWS API Gateway VTL无法正确处理Map类型JSON序列化问题
问题分析与解决
问题根源
当前映射模板写法存在两个核心问题:
- 在Velocity模板中直接用
{ "A": { "N": "$inputRoot.data.a" } }这种对象字面量形式,会被模板引擎解析为Velocity哈希表对象,而非标准JSON字符串,最终输出时会变成A={N=0.37}这类非规范格式,不符合DynamoDB的JSON序列化要求。 $util.escapeJavaScript是用于转义JavaScript特殊字符的工具,并非生成标准JSON的方法,用它处理Velocity哈希对象只会进一步打乱格式。
正确的映射模板写法
要生成符合DynamoDB要求的JSON格式(尤其是M类型的嵌套结构),可以采用以下两种可行方案:
方案1:直接拼接标准JSON字符串
这种方式能精准控制输出格式,避免模板引擎的自动解析干扰:
#set($aVal = $inputRoot.data.a) #set($bVal = $inputRoot.data.b) { "MyColumn": { "M": { "A": { "N": "$aVal" }, "B": { "N": "$bVal" } } } }
方案2:用$util.toJson处理合法Velocity对象
若需动态构建对象,先创建完整的Velocity哈希表,再转换为JSON:
#set($innerMap = {}) #set($ignore = $innerMap.put("A", { "N": $inputRoot.data.a })) #set($ignore = $innerMap.put("B", { "N": $inputRoot.data.b })) { "MyColumn": { "M": $util.toJson($innerMap) } }
注意:如果$inputRoot.data.a/$inputRoot.data.b是字符串类型,需确保其能被DynamoDB识别为数字,必要时用$util.parseNumber($inputRoot.data.a)做类型转换
之前尝试失败的原因
- 直接用
{...}构造的是Velocity哈希对象,输出时会采用Velocity的对象toString格式,而非标准JSON结构。 $util.toJson之前抛出内部错误,是因为传入的不是可正常序列化的Velocity对象(比如直接嵌套了未处理的模板变量引用),改用先构建完整哈希表再转换的方式即可规避。
内容的提问来源于stack exchange,提问作者MH7086
相关产品推荐
相关产品推荐

