问题描述
我正在使用Ballerina语言按照here中的指示为在线零售商店中的订单管理创建RESTful Web服务。在处理HTTP PUT请求的资源函数中,有一段代码将从json映射对象(当前用于存储订单,尚未连接数据库)中检索相关订单,并使用来更新其某些字段。 HTTP PUT请求收到的json对象中的内容。
我已经声明了json地图对象ordersMap。
map<json> ordersMap = {};
// Get the json obejct from the payload
var updatedOrder = <@untained> req.getJsonPayload();
// Get the existing order that is required by the request from the json map object.
json existingOrder = ordersMap[orderId];
// Updating the necessaries and saving it in the map object.
existingOrder.Order.Name = updatedOrder.Order.Name;
existingOrder.Order.Description = updatedOrder.Order.Description;
ordersMap[orderId] = existingOrder;
当我尝试编译程序时,编译器会引发以下错误。
无效操作:键入“ json”不支持分配的字段访问
我一直在网上寻找解决方案,但找不到任何东西。 我正在使用芭蕾舞女演员1.2.4
解决方法
这是因为当您使用json
数据类型时,编译器无法保证您所访问的字段存在,并且(如果不存在,则无法计算出要插入相关条目的类型)。
当您想对一段json数据进行操作,并且知道此json结构的形状时,创建相关类型并对其进行操作是个好主意,如果您想要json,则可以将其转换回到json。不幸的是,在Ballerina 1.2.x中没有直接的方法可以从json转换(和转换),如果您可以切换到Ballerina Swanlake轨道,则可以使用以下代码。
import ballerina/io;
type Info record {
User user;
};
type User record {
string name;
string bal_version;
};
public function main() returns error? {
json j = { user: { name: "Hiran",bal_version: "1.2.4"}};
json k = { user: { name: "Hiran-New",bal_version: "1.2.4"}};
io:println(j);
// Convert json to expected datatype.
Info|error info = j.fromJsonWithType(Info);
if (info is Info) {
Info kInfo = check k.fromJsonWithType(Info);
info.user.name = kInfo.user.name;
// convert back to json
json newJ = info.toJson();
io:println(newJ);
} else {
// Expected json schema did not match.
// Handle the error here.
}
}
在芭蕾舞女演员1.2.x中
import ballerina/io;
public function main() returns error? {
json j = { user: { name: "Hiran",bal_version: "1.2.4"}};
io:println(j);
map<json> mj = <map<json>> j;
map<json> user = <map<json>> mj.get("user");
user["name"] = <string> k.user.name;
// note,we update the original json value.
io:println(j);
}
第二种方法的一个大问题是,如果传入的json值的结构与我们预期的不同,则会因类型转换错误而导致恐慌。
,如果您使用的是Ballerina 1.2.4,我强烈建议您更新到最新的Ballerina 1.2.x版本(当前是1.2.8,更快是1.2.9)。它们是向后兼容的。因此,更新应该没有任何问题。
谈到您的问题,您可以使用.
运算符来访问JSON中的字段。看下面的例子。
如果知道结构的确切形状,则可以使用定义的record
类型。然后,您可以使用constructFrom()
函数构造记录。否则,您也可以使用.
运算符访问字段。
在这两种情况下,请确保相应地处理该错误。我使用checkpanic
只是为了显示功能,但是您可以更好地处理它。
import ballerina/io;
type Address record {
string no;
string street;
string city;
};
type Person record {
string name;
Address address;
};
public function main() {
json j = getJson();
Person p = checkpanic Person.constructFrom(j);
io:print("Person Record: ");
io:println(p);
json address = checkpanic j.address;
io:print("Address field from JSON: ");
io:println(address);
}
function getJson() returns json {
json j = {
name: "Sherlock",address: {
no: "221/B",street: "Baker Street",city: "London"
}
};
return j;
}
这将打印以下内容:
Person Record: name=Sherlock address=no=221/B street=Baker Street city=London
Address field from JSON: no=221/B street=Baker Street city=London
在Ballerina 1.2.8上进行了尝试。
您可以查看更多examples here。