首页 > 解决方案 > 根据 Java8 中的逻辑表达式验证 JSON

问题描述

我有一个字符串格式的表达式。

String exp = "(weight > 50 && height > 150 && height < 160) || BP = 130";

我从一个 JSON 对象创建了这个字符串。因此可以灵活地转换为任何格式。

现在我有一个 JSON 格式的用户数据。

{
  "weight": 55,
  "height": 155,
  "BP": 130
}

我将如何根据上述表达式验证用户的 JSON 详细信息。我期待基于表达式验证的真/假结果。

标签: javajava-8expressionexpression-evaluation

解决方案


得知没有这样的事情可以完全按照您的意愿去做,您可能并不感到惊讶。你必须自己写。

有两个主要步骤:解析器和解释器。构建此代码的逻辑方法是使用解释器模式

您应该构建一系列表达式,每个表达式都能够说明它是否与给定的 json 匹配。

interface Expression {
    boolean matches(JsonObject json);
}

对于您的示例,您将需要:

  • 大于表达式 (key > val)
  • 小于表达式 (key < val)
  • 等于表达式 (key = val)
  • 表达式 (expr && expr2)
  • 表达式 (expr || expr2)

括号不需要自己的表达式。

这是 And 表达式的外观示例。它只是服从两个委托并执行逻辑与。

以下代码均假设使用Gson,但您可以使用任何 json 解析库。

class AndExpression implements Expression {
    private final Expression a;
    private final Expression b;

    AndExpression(Expression a, Expression b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean matches(JsonObject json) {
        return a.matches(json) && b.matches(json);
    }
}

equals 表达式有点复杂。它需要寻找键的存在,获取值,然后进行比较。

class EqualsExpression implements Expression {
    private final String key;
    private final String value;

    EqualsExpression(String key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public boolean matches(JsonObject json) {
        if (json.has(key)) {
            final JsonElement elem = json.get(key);
            if (elem.isJsonPrimitive()) {
                return elem.getAsJsonPrimitive().getAsString().equals(value);
            }
        }
        return false;
    }
}

要对表达式建模,foo = bar && bar = baz您可以将这两个类组合在一起,如下所示:

Expression fullExpression = new AndExpression(
    new EqualsExpression("foo", "bar"),
    new EqualsExpression("bar", "baz")
);

您将需要实现其他 3 个表达式,根据我给您的内容,这应该是微不足道的,并且需要一个解析器来根据您的文本输入动态创建和组合表达式。


推荐阅读