ColdFusion:如何检查JSON属性是否为空?

6
假设我发送了以下简单的JSON数据包:

{"foo":null}

在 ColdFusion 服务器上,我该如何检查 'foo' 属性是否为 null?

IsDefined 方法无法起作用,因为它会返回 false 值(null 值)。IsNull 方法也不能准确判断,因为它不仅对 null 值返回 true 值,还对未定义属性返回 true 值。

<cfset json = DeserializeJSON(GetHttpRequestData().content) />
<cfdump var="#IsDefined("json.foo")#" /> <!--- false --->
<cfdump var="#IsNull(json.foo)#" /> <!--- true --->
<cfdump var="#IsNull(json.bar)#" /> <!--- true --->
4个回答

15

我的错误,我以为在JSON中null会被反序列化为空字符串,但事实并非如此。

在JSON中,null被翻译成具有键foo但在CF10中未定义的结构体。(不确定旧版本的CF)

输入图像描述

因此,一个真正的isStructValueNull()可以这样写:

function isStructValueNull(struct, key) {
    return listFind(structKeyList(struct), key) 
             && !structKeyExists(struct, key);
}

json = deserializeJSON('{"foo":null,"bar":123}');

writeDump(isStructValueNull(json, "foo"));    // yes
writeDump(isStructValueNull(json, "bar"));    // no

或者您可以循环遍历json并使用structKeyExists(),如果为false,则为null。

function structNullKeyList(struct) {
    var nulls = "";
    for (var key in struct) 
       if (!structKeyExists(struct, key))
         nulls = listAppend(nulls, key);
    return nulls;
}

writeDump(structNullKeyList(json));           // 'foo'

1
虽然这很痛苦(就像 ColdFusion 中的大多数事情一样),但似乎这是 CF10 中最好的方法。 - Johnny Oshika

0
你是如何发布这些数据的?当你仅转储变量“json”时,你得到了什么?
如果你正在向ColdFusion发布数据,每个参数都应该被转换为一个FORM作用域变量。检查你的HTTP POST的头部,看看数据是如何发送的。
如果它们被作为单独的参数发送,你应该能够检查<cfif structKeyExists(form, "foo")>,然后检查form.foo的值是否为空字符串。(ColdFusion将NULL值转换为空字符串。)

只有当内容类型为application/x-www-form-urlencoded时,它才是仅限于表单范围的。我正在使用JSON,因此它不会被限制在表单范围内。 - Johnny Oshika

0

我使用Railo。

Railo 4.1.3.005 错误(表达式) 消息键[FOO]的值为NULL,这与CFML中不存在相同。

但是我们可以使用完全的Null支持。在这里,它可以被适当地检查,就像你想要的那样。

<cfscript>

    objectValues = { 'one' : 1 , 'two' : 2 , 'three' : JavaCast( "null", 0 ) , 'four' : null };

    dump(objectValues);

    // Known existing attribute
    dump('three');
    dump( isDefined('objectValues.three') );
    dump( isNull(objectValues.three) );
    dump( StructKeyExists(objectValues,'three') );

    // Known Railo Null value
    dump('four');
    dump( isDefined('objectValues.four') );
    dump( isNull(objectValues.four) );
    dump( StructKeyExists(objectValues,'four') );

    // Unknown existing attribute
    dump('five');
    dump( isDefined('objectValues.five') );
    dump( isNull(objectValues.five) );
    dump( StructKeyExists(objectValues,'five') );

</cfscript>

你的ColdFusion版本是什么?


0

实际上,Coldfusion应该将真正的JSON null值翻译为“null”,这同样令人讨厌但可管理。

如果您只是像这样在结构中存储一个空字符串:

<cfset s = StructNew()>
<cfset s.test = "" />
<cfset json = SerializeJSON(s)>
<cfdump var="#json#">
<cfset d = DeserializeJSON(json)>
<cfdump var="#d#">

你会得到以下的json: {"TEST":""} 和 d.test 是 ""
但是如果你明确地在结构体中存储一个Java null,就像这样:
<cfset s = StructNew()>
<cfset s.test = javaCast( "null", "" ) />
<cfset json = serializeJSON(s)>
<cfdump var="#json#">
<cfset d = DeserializeJSON(json)>
<cfdump var="#d#">

您将获得以下JSON值:{"TEST":null},而d.test是“null”

这可能更可取,因为您可以这样做:

<cfif StructKeyExists(d,"TEST") AND Compare(d.test,"null") IS 0>

1
在CF10中,d.test不是'null'。我尝试转储d.test,它显示“在D中未定义元素TEST”。 - Henry
旧版的CF将null翻译成了“null”?哎呀。我无法验证这一点,因为我正在使用CF10。 - Johnny Oshika

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接