如何检查值是apache velocity中的映射还是字符串

时间:2014-10-15 08:58:30

标签: velocity

我使用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开启此工作?

3 个答案:

答案 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是输入参数的映射。