我想在服务器端验证传入的json对象的正确性。有没有标准/最佳方式来做到这一点?你的验证方法是什么?
答案 0 :(得分:5)
我的建议 - 反序列化JSON并查看它是否中断。例如,如果您在服务器端使用C#,则可以使用新的DataContractJsonSerializer
,或者使用JavaScriptSerializer
以旧的方式执行此操作,这可以说更简单。
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<Dictionary<string, object>>(jsonString);
编辑:现在已经知道你正在使用Java,当然我的C#示例对你不起作用,但概念是一样的。 Stackoverflow已经有一些答案here:Convert a JSON string to object in Java ME?
答案 1 :(得分:3)
使用JSON库对其进行解码。如果使用符合规范的库成功解码,那么它就是有效的。
答案 2 :(得分:0)
我可以从您的评论中得出结论,您首先要确保json对象有效,如果有效,则可以创建Java对象。无论您的论点是什么,validol库都允许您声明性地声明复杂的验证规则,如果验证规则成功,则将导致产生Java对象。
假设您有一个订单注册请求,该请求包括几个块,包括payment
。为了简洁起见,我忽略了除那个之外的所有块。在这种情况下,此请求的外观如下:
{
"payment":{
"expires_at":"12/29",
"card_number":12345612341234
}
}
这是验证码:
/*1 */ public class ValidatedRegistrationRequest implements Validatable<RegistrationRequest>
{
private String jsonRequestString;
private Connection dbConnection;
/*6 */ public ValidatedRegistrationRequest(String jsonRequestString, Connection dbConnection)
{
this.jsonRequestString = jsonRequestString;
this.dbConnection = dbConnection;
}
@Override
/*13*/ public Result<RegistrationRequest> result() throws Exception
{
return
/*16*/ new FastFail<>(
/*17*/ new WellFormedJson(
/*18*/ new Unnamed<>(Either.right(new Present<>(this.jsonRequestString)))
),
/*20*/ requestJsonObject ->
/*21*/ new UnnamedBlocOfNameds<>(
/*22*/ List.of(
/*23*/ new FastFail<>(
/*24*/ new IsJsonObject(
/*25*/ new Required(
/*26*/ new IndexedValue("payment", requestJsonObject)
)
),
/*29*/ paymentJsonObject ->
/*30*/ new NamedBlocOfNameds<>(
/*31*/ "payment",
/*32*/ List.of(
/*33*/ new CardIsNotExpired(
/*34*/ new AsString(
/*35*/ new Required(
/*36*/ new IndexedValue("expires_at", paymentJsonObject)
)
)
),
/*40*/ new CardNumberIsNotBlacklisted(
/*41*/ new CardNumberSatisfiesLuhnAlgorithm(
/*42*/ new Required(
/*43*/ new IndexedValue("card_number", paymentJsonObject)
)
),
/*46*/ this.dbConnection
)
),
/*49*/ Payment.class
)
)
),
/*53*/ RegistrationRequest.class
)
)
.result();
}
}
让我们逐行查看发生的事情:
Line 1
ValidatedRegistrationRequest
的声明。
Line 6
其构造函数接受尚未解析的json字符串。它可能来自传入的请求,收到的响应或几乎其他任何地方。
Line 13
:调用此方法时,验证开始。
Line 16
:更高级别的验证对象是FastFail
块。如果第一个参数无效,则会立即返回错误。
Lines 17-19
:检查json是否格式正确。如果是后者,则验证会很快失败并返回相应的错误。
Line 20
:如果json格式正确,则调用闭包,并将json数据作为其单个参数传递。
Line 21
:已验证json数据。它的结构是一个未命名的已命名块。它对应于JSON对象。
Line 26
:第一个(也是唯一的)块称为payment
。
Line 25
:这是必需的。
Line 24
:它必须是json对象。
Line 23
:如果不是,则错误将立即返回,因为它是FailFast
对象。
Line 29
:否则,将调用闭包。
Line 30
:付款区块是由其他命名条目(对象或标量)组成的命名区块。
Line 36
:第一个称为expires_at
Line 35
:这是必需的。
Line 34
:并且如果可能的话,表示为字符串。如果没有,将返回错误。
Line 33
:最后,检查它是否未过期。
Line 43
:第二个参数称为card_number
。
Line 42
:这也是必需的。
Line 41
:必须满足Luhn算法。
Line 40
:而且不应在我们的数据库中将其列入黑名单,因此……
Line 46
:…this.dbConnection
参数。
Line 49
:如果所有先前的验证检查都成功,那么将创建类Payment
的对象。
Line 53
:最后,创建并返回RegistrationRequest
。
验证成功后,调用代码的外观如下:
Result<RegistrationRequest> result = new ValidatedRegistrationRequest(jsonRequestString).result();
result.isSuccessful();
result.value().raw().payment().cardNumber(); // 12345612341234
您可以找到有关declarative validation方法的更多信息,或直接进入quick start条目以获取更多示例。