3 回答

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊
您可以stream
為 POJO 中的所有字段創(chuàng)建并可以檢查 null
return Stream.of(id, name).anyMatch(Objects::isNull);
或者
return Stream.of(id, name).allMatch(Objects::isNull);

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超7個(gè)贊
我不想逐個(gè)字段做空檢查
您可以避免自己編寫(xiě)支票,但您需要“標(biāo)記”字段上的約束。
并使用 Validator 顯式驗(yàn)證實(shí)例。
請(qǐng)注意,帶注釋的字段null
在某個(gè)上下文中可能是強(qiáng)制性的,而null
在另一個(gè)上下文中則不一定。并且它與這種方式兼容,因?yàn)轵?yàn)證器將僅在請(qǐng)求時(shí)驗(yàn)證對(duì)象:即按需。
根據(jù)您的評(píng)論:
我正在開(kāi)發(fā)代碼庫(kù),而您的解決方案具有侵入性。我將不得不接觸創(chuàng)建該 pojo 的低級(jí) json 解析器。我不想那樣做
在這種情況下,您可以使用要驗(yàn)證的當(dāng)前類(lèi)外部的 Map。
它將允許維護(hù)您驗(yàn)證的字段的名稱(chēng)并在錯(cuò)誤消息中使用它(對(duì)調(diào)試很有用)。
例如 :
Foo foo = new Foo();
// set foo fields...
// expected null but was not null
Map<String, Object> hasToBeNullMap = new HashMap<>();
hasToBeNullMap.put("x", foo.getX());
hasToBeNullMap.put("y", foo.getY());
hasToBeNullMap.put("z", foo.getZ());
String errrorMessageForNullExpected = getErrorFieldNames(hasToBeNullMap, Objects::nonNull);
// expected not null but was null
Map<String, Object> hasToBeNotNullMap = new HashMap<>();
hasToBeNotNullMap.put("z", foo.getZ());
String errrorMessageForNotNullExpected = getErrorFieldNames(hasToBeNotNullMap, o -> o == null);
private static String getErrorFieldNames(Map<String, Object> hasToBeNullMap, Predicate<Object> validationPred) {
? ? return hasToBeNullMap.entrySet()
? ? ? ? ? ? ? ? ? ? ? ? ?.stream()
? ? ? ? ? ? ? ? ? ? ? ? ?.filter(validationPred::test)
? ? ? ? ? ? ? ? ? ? ? ? ?.map(Entry::getKey)
? ? ? ? ? ? ? ? ? ? ? ? ?.collect(joining(","));
}

TA貢獻(xiàn)1779條經(jīng)驗(yàn) 獲得超6個(gè)贊
如果對(duì)象中只有幾個(gè)字段,并且您知道它不會(huì)經(jīng)常更改,則可以Stream.of按照 Deadpool 的回答將它們列為參數(shù)。缺點(diǎn)是違反了 DRY 原則:您重復(fù)字段名稱(chēng):一次在 POJO 定義中,再次在參數(shù)列表中。
如果您有很多字段(或不想重復(fù)自己),您可以使用反射:
boolean valid = Stream.of(YourPojoClass.class.getDeclaredFields())
.filter(f -> !(f.getName().equals("fieldname allowed to be null") || f.getName.equals("the other field name")))
.allMatch(f -> {
f.setAccessible(true);
try {
return f.get(o) == null;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
請(qǐng)注意,使用反射可能會(huì)產(chǎn)生很小的性能損失,與解析從 Web 服務(wù)獲得的 JSON 字符串相比可能微不足道。
如果您有原始字段(例如int, boolean, char)并且您希望將它們包含在檢查中,將它們限制為默認(rèn)值(0, false, '\0'),則使用以下代碼:
.allMatch(f -> {
f.setAccessible(true);
try {
return (f.getType() == boolean.class && f.getBoolean(o) == false)
|| (f.getType().isPrimitive() && f.getDouble(o) == 0)
|| f.get(o) == null;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
添加回答
舉報(bào)