UI5中无需第三方工具,能否基于JSON Schema验证JSON数据?
确实,UI5并没有提供开箱即用的原生JSON Schema验证工具,不过针对复杂嵌套的JSON结构,我们可以结合UI5现有能力来实现自定义验证,下面是几个可行的思路:
1. 结合UI5数据类型与递归遍历
虽然直接用sap/ui/base/DataType或sap/ui/model/SimpleType处理深层嵌套结构比较麻烦,但我们可以自己编写递归遍历函数,对JSON的每个层级属性调用对应UI5数据类型的验证方法。核心思路是将自定义的结构规则与UI5原生数据类型绑定,递归遍历完成全结构验证。
举个简单的实现示例:
function validateNestedData(oData, oSchema) { const aErrors = []; for (const sProp in oSchema) { const oPropSchema = oSchema[sProp]; const vValue = oData[sProp]; // 递归验证子对象 if (oPropSchema.type === "object" && typeof vValue === "object" && vValue !== null) { const aChildErrors = validateNestedData(vValue, oPropSchema.properties); if (aChildErrors.length) { aErrors.push(...aChildErrors.map(sErr => `${sProp}.${sErr}`)); } } // 验证数组内的每个元素 else if (oPropSchema.type === "array" && Array.isArray(vValue)) { vValue.forEach((oItem, iIndex) => { const aItemErrors = validateNestedData(oItem, oPropSchema.items.properties); if (aItemErrors.length) { aErrors.push(...aItemErrors.map(sErr => `${sProp}[${iIndex}].${sErr}`)); } }); } // 用UI5数据类型验证单个属性 else { try { const oType = sap.ui.model.type.SimpleType.fromConfig(oPropSchema.ui5TypeConfig); oType.validateValue(vValue); } catch (oError) { aErrors.push(`${sProp}: ${oError.message}`); } } } return aErrors; } // 自定义结构规则示例(绑定UI5数据类型配置) const oMySchema = { user: { type: "object", properties: { id: { ui5TypeConfig: { className: "sap.ui.model.type.Integer" } }, name: { ui5TypeConfig: { className: "sap.ui.model.type.String", constraints: { minLength: 2 } } }, addresses: { type: "array", items: { type: "object", properties: { street: { ui5TypeConfig: { className: "sap.ui.model.type.String" } }, zipCode: { ui5TypeConfig: { className: "sap.ui.model.type.String", constraints: { regex: "^\\d{5}$" } } } } } } } } };
这个方法的优势是错误信息会带上层级路径,方便快速定位问题,而且完全基于UI5原生能力实现。
2. 利用OData模型的元数据验证(场景适配时)
如果你的JSON数据来自OData服务,可以直接借助UI5的OData模型(sap.ui.model.odata.v2.ODataModel或v4版本)完成验证。这类模型会自动根据服务端的EDM元数据来校验数据类型,当数据不符合元定义时,会触发validationError事件,你可以通过监听该事件捕获错误。
这种方式无需手动编写验证逻辑,前提是你的数据来源是OData服务,且服务端元数据定义完整。示例代码如下:
const oODataModel = new sap.ui.model.odata.v2.ODataModel("/your/odata/service/path", { defaultBindingMode: "TwoWay" }); // 监听验证错误 oODataModel.attachValidationError(function(oEvent) { const oParams = oEvent.getParameters(); console.error(`Validation error at path ${oParams.path}: ${oParams.message}`); });
3. 自定义验证器结合UI5绑定验证
如果你的JSON数据需要绑定到UI控件,可以给每个绑定路径添加自定义验证逻辑。对于嵌套属性,同样可以用递归方式为每个子属性绑定验证函数,实现验证与UI联动。
示例代码:
function addNestedValidators(oBinding, oSchema) { for (const sProp in oSchema.properties) { const oPropSchema = oSchema.properties[sProp]; const sFullPath = `${oBinding.getPath()}/${sProp}`; const oPropertyBinding = oBinding.getModel().bindProperty(sFullPath); // 递归处理子对象 if (oPropSchema.type === "object") { addNestedValidators(oPropertyBinding, oPropSchema); } else { // 设置UI5数据类型 const oType = sap.ui.model.type.SimpleType.fromConfig(oPropSchema.ui5TypeConfig); oPropertyBinding.setType(oType); // 监听验证错误 oPropertyBinding.attachValidationError(function(oEvent) { console.error(`Validation error at ${sFullPath}: ${oEvent.getParameter("message")}`); }); } } } // 调用示例(假设已有模型和根绑定) const oRootBinding = oModel.bindProperty("/"); addNestedValidators(oRootBinding, oMySchema);
这种方式适合需要在界面上直接反馈验证错误的场景,验证逻辑与UI绑定深度联动。
总的来说,虽然UI5没有官方的JSON Schema直接验证工具,但通过上述几种基于UI5原生能力的方案,完全可以实现复杂嵌套JSON的验证需求,全程无需依赖第三方库。
内容的提问来源于stack exchange,提问作者xac

