看起来您并没有绑定到 JSONSchema,尽管它似乎是您的默认选择。口味不同,但通常看起来更复杂。此外,就个人而言,我希望将数据和验证规则放在同一个地方。当在 java 代码中而不是任何类型的配置文件中使用时,自定义验证器似乎更自然地适合。
这是这种方法的样子。比如说,您有以下 json 对象表示一些付款(无论是请求还是响应),但为简洁起见仅包含discount
块:
{
"discount":{
"valid_until":"2032-05-04 00:00:00+07",
"promo_code":"VASYA1988"
}
}
这是验证代码的样子:
/*1 */ public class ValidatedJsonObjectRepresentingRequestOrResponse implements Validatable<JsonObjectRepresentingRequestOrResponse>
{
private String jsonString;
private Connection dbConnection;
/*6 */ public ValidatedJsonObjectRepresentingRequestOrResponse(String jsonString, Connection dbConnection)
{
this.jsonString = jsonString;
this.dbConnection = dbConnection;
}
@Override
/*13*/ public Result<JsonObjectRepresentingRequestOrResponse> result() throws Exception
{
return
/*16*/ new FastFail<>(
/*17*/ new WellFormedJson(
/*18*/ new Unnamed<>(Either.right(new Present<>(this.jsonRequestString)))
/*19*/ ),
/*20*/ requestJsonObject ->
/*21*/ new UnnamedBlocOfNameds<>(
List.of(
/*23*/ new FastFail<>(
/*24*/ new IsJsonObject(
/*25*/ new Required(
/*26*/ new IndexedValue("discount", requestJsonObject)
)
),
/*29*/ discountObject ->
/*30*/ new NamedBlocOfNameds<>(
/*31*/ "discount",
/*32*/ List.of(
/*33*/ new PromoCodeIsNotExpired(
/*34*/ new AsString(
/*35*/ new Required(
/*36*/ new IndexedValue("valid_until", discountObject)
)
)
),
/*40*/ new PromoCodeIsNotAlreadyRedeemed(
/*41*/ new PromoCodeContainsBothLettersAndDigits(
/*42*/ new Required(
/*43*/ new IndexedValue("promo_code", discountObject)
)
),
/*46*/ this.dbConnection
)
),
/*49*/ Discount.class
)
)
),
/*53*/ JsonObjectRepresentingRequestOrResponse.class
)
)
.result();
}
}
让我们逐行看看这里发生了什么:
Line 1
的声明ValidatedJsonObjectRepresentingRequestOrResponse
。
Line 6
它的构造函数接受原始 json 字符串。它可能是传入的请求或收到的响应,或者几乎是其他任何东西。
Line 13
: 验证在调用此方法时开始。
Lines 16
:更高级别的验证对象是FastFail
块。如果第一个参数无效,则立即返回错误。
Lines 17-19
: 检查 json 格式是否正确。如果是后者,验证会很快失败并返回相应的错误。
Line 20
:如果 json 格式正确,则调用闭包,并将 json 数据作为其单个参数传递。
Line 21
: json 数据被验证。它的结构是命名块的未命名块。它对应一个 JSON 对象。
Line 26
: 第一个(也是唯一的)块被调用discount
。
Line 25
: 必须的。
Line 24
: 它必须是一个 json 对象。
Line 23
: 如果不是,将立即返回错误,因为它是一个FailFast
对象。
Line 29
: 否则,调用闭包。
Line 30
: Discount
block 是一个命名块,由其他命名条目(对象或标量)组成。
Line 36
: 第一个叫做valid_until
Line 35
: 是必须的。
Line 34
:如果它真的是一个字符串,则表示为一个字符串。如果不是,将返回一个错误。
Line 33
: 最后,检查它没有过期。
Line 43
: 第二个参数被调用promo_code
。
Line 42
: 也是必须的。
Line 41
: 它必须包含字母和数字。
Line 40
: 而且它不应该已经被赎回了。这个事实肯定会保存在我们的数据库中,因此 ...<br>
Line 46
: ...this.dbConnection
参数。
Line 49
:如果所有先前的验证检查都成功,Discount
则创建一个类对象。
Line 53
: 最后,JsonObjectRepresentingRequestOrResponse
被创建并返回。
以下是验证成功时调用代码的外观:
Result<JsonObjectRepresentingRequestOrResponse> result = new ValidatedJsonObjectRepresentingRequestOrResponse(jsonRequestString).result();
result.isSuccessful();
result.value().raw().discount().promoCode(); // VASYA1988
这个例子取自这里。在这里您可以找到一个完整的json 请求验证示例。