我使用apache velocity来渲染模板。现在,问题是我有一个API数据源,其值可以包含地图或字符串。我遍历列表并将值放在表中。这是饲料的样本:
{
"Secondary Camera":
{
"Key1":
{
"present": "true",
"value": "2 Megapixel"
},
"Key2":
{
"present": "true","value": "0.3 Megapixel"
}
}
},
{
"Other Camera Features":
{
"Key1": "Auto Focus, Panorama, Photo Sphere, Lens Blur",
"Key2": "Panorama Shot"
}
},
使用此键,Key1 / Key2值有时是字符串,有时它们是地图。是否有一种简单的方法可以使strict mode开启此工作?
答案 0 :(得分:1)
有一种方法。主要思想是直接检查价值观类。
以下代码
#set(
$map = {
'key1' : 'string_value',
'key2' : [ 'array', 'value' ],
'key3' : { 'map' : 'value' }
}
)
#set ( $obj = '' ) ## dummy object
#set ( $string_class = $obj.class.forName('java.lang.String') )
#set ( $map_class = $obj.class.forName('java.util.Map') )
#foreach( $value in $map )
value class name = $value.class.name
#if ( $string_class.isAssignableFrom($value.class) )
value is a string
#elseif ( $map_class.isAssignableFrom($value.class) )
value is a map
#end
#end
将产生:
value class name = java.lang.String
value is a string
value class name = java.util.LinkedHashMap
value is a map
您还可以直接测试对象是否为$obj.class.name == 'java.lang.String'
的类,但是您不能以这种方式对地图执行此操作,因为java.util.Map
只是所有地图类的根抽象接口。
警告:某些Velocity配置(称为 secure )将禁止访问对象的class
属性。
答案 1 :(得分:0)
在尝试获取APIGateway的通用VTL模板时,我遇到了这种情况,这种情况在这种特定环境下仍然有效。显然,当将toString()应用于Map时,此字符串将显示为“ [object Object]”,因此我们可以使用此技巧来区分Map和其他类型。这不需要访问“类”。依靠这种hack感觉并不特别健壮,但是到目前为止,这是我得到的最好的结果。所以我在这里分享记录。
#if ($cdrField.toString() != "[object Object]")
答案 2 :(得分:0)
我尝试了@ claude-brisson的答案,但无法在AWS AppSync上使用。我的方法不太复杂,我讨厌它通过对象的字符串名称检查对象的类,但是它可以完成工作。
#foreach( $entry in $ctx.args.entrySet() )
#if( $entry.value.class.name == "java.util.LinkedHashMap" )
##Do something if value is a map
#elseif( $entry.value.class.name == "java.lang.String" )
##Do something if value is a string
#elseif( $entry.value.class.name == "java.util.ArrayList" )
##Do something if value is a list
#end
#end
$ctx.args
是输入参数的映射。