В моем веб-приложении мне нужно проверить многие параметры входящего запроса из requestBody. Чтобы не писать один и тот же код в каждом методе, я хочу написать функцию, которая возвращает логическое значение. Когда все необходимые параметры получены и значения entrySet не равны нулю, метод должен вернуть true (иначе false), я могу использовать входящие параметры запроса позже в программе.
Поэтому я упаковываю все входящие параметры в HashMap. Кроме того, я помещаю в метод определенный список, который предоставляет необходимые параметры (ключи) для проверки.
Пример карты queryParams:
Map queryParams = new HashMap();
queryParams.put("id", "1");
queryParams.put("name", "Jane");
queryParams.put("lastname", "Doe");
Пример массива:
String[] keys = {"id", "name", "lastname"};
Последняя версия метода:
public static Boolean checkRequestParams(Request request, String[] keys) {
Map params = (JsonUtil.fromJson(request.body(), HashMap.class));
Iterator it = params.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
for (int i = 0; i < keys.length; i++) {
if (pair.getKey().equals(keys[i])) {
return true;
}
}
Массив предоставляет ключи, которые являются параметрами QueryParams, отправленными клиентом. Нет, я хочу сравнить их и проверить, равны ли ключи в Hashmap заданным ключам в массиве и не равны ли значения ключей на карте null.
Я пробовал много вариаций. Либо я получил nullPointerExceptions, либо я всегда возвращал null.
Не используйте необработанные типы и предоставляйте данные, которые вы передаете в качестве входных данных, и то, что вы ожидаете. Там слишком широко.
спасибо, да, это была ошибка, исправил.
Все это звучит так, как будто очень хочется пройти валидацию JSR-303.
{"id, имя, фамилия"}; должно быть {"id", "имя", "фамилия"}




Я могу ошибаться, но, как я понял, вы хотите проверить следующее условие:
{"id", "name", "lastname"}.Вы можете использовать что-то похожее на это:
map.entrySet()
.stream()
.allMatch(entry -> keys.contains(entry.getKey()) && entry.getValue() != null)
Итак, мы перебираем набор записей и проверяем, принадлежит ли ключ записи определенному набору и не равно ли значение null. Вот более подробный пример:
Set<String> keys = Set.of("id", "name", "lastname");
Map<String,List<Integer>> map = Map.of("id", List.of(1,2,3), "name", List.of(4,5,6));
map.entrySet()
.stream()
.allMatch(entry -> keys.contains(entry.getKey()) && entry.getValue() != null);
Map<String,List<Integer>> map1 = Map.of("id", List.of(1,2,3), "not in the keys", List.of(4,5,6));
map1.entrySet()
.stream()
.allMatch(entry -> keys.contains(entry.getKey()) && entry.getValue() != null);
Обратите внимание, что я использую фабричные методы коллекций для создания Map, List и Set, которые были добавлены в java-9, но потоковый API доступен с java-8.
Что касается вашего кода, вы всегда будете получать true, потому что как только существует набор записей, удовлетворяющий условию, метод вернет результат.
for (int i = 0; i < keys.length; i++) {
if (pair.getKey().equals(keys[i])) {
return true; // one single match found return true.
}
}
Вы можете попытаться изменить условие и вернуть false, как только возникнет несоответствие.
for (int i = 0; i < keys.length; i++) {
if (!pair.getKey().equals(keys[i]) || pair.getValue() == null) {
return false; // mismatch found, doesn't need to verify
// remaining pairs.
}
}
return true; // all pairs satisfy the condition.
Я надеюсь, что вы найдете это полезным.
Что вы хотите проверить, содержит ли keys все ключи map или содержит ли map все элементы keys?
содержит ли карта все элементы ключей.
@Hubi, тогда это противоположность этому ответу.
Не должен возвращаться немедленно, если найдено совпадение, поскольку мы хотим проверить «все необходимые» параметры. Попробуйте что-то вроде:
String[] keys = {"id, "name", "lastname"};
public static Boolean checkRequestParams(Request request, String[] keys) {
Map params = (JsonUtil.fromJson(request.body(), HashMap.class));
for (int i = 0; i < keys.length; i++) {
Iterator it = params.entrySet().iterator();
boolean found = false;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
if (pair.getKey().equals(keys[i])) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
Просто используя ванильную Java, вы можете попробовать что-то вроде этого.
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ValidatorExample {
public boolean checkRequestParams(Map<String, Object> request, List<String> keys) {
return isEqualCollection(request.keySet(), keys)
&& !containsAnyNull(request.values());
}
private boolean isEqualCollection (Collection<?> a,Collection<?> b){
return a.size() == b.size()
&& a.containsAll(b)
&& b.containsAll(a);
}
private boolean containsAnyNull(Collection<?> collection){
return collection.contains(null);
}
public static void main(String[] args) {
ValidatorExample validatorExample = new ValidatorExample();
List<String> keys = Arrays.asList("id", "name", "lastname");
Map<String, Object> parametersOk = new HashMap<>();
parametersOk.put("id", "idValue");
parametersOk.put("name", "nameValue");
parametersOk.put("lastname", "lastnameValue");
// True expected
System.out.println(validatorExample.checkRequestParams(parametersOk, keys));
Map<String, Object> parametersWithInvalidKey = new HashMap<>();
parametersWithInvalidKey.put("id", "id");
parametersWithInvalidKey.put("name", "nameValue");
parametersWithInvalidKey.put("lastname", "lastnameValue");
parametersWithInvalidKey.put("invalidKey", "invalidKey");
// False expected
System.out.println(validatorExample.checkRequestParams(parametersWithInvalidKey, keys));
Map<String, Object> parametersWithNullValue = new HashMap<>();
parametersWithNullValue.put("id", null);
parametersWithNullValue.put("name", "nameValue");
parametersWithNullValue.put("lastname", "lastnameValue");
// False expected
System.out.println(validatorExample.checkRequestParams(parametersWithNullValue, keys));
}
}
Но я бы порекомендовал вам использовать структуру проверки, если ваш проект позволяет проводить более точную проверку.
Вы возвращаете true для первого совпадающего ключа, тогда как вы хотите проверить, присутствуют ли ключи все. Далее, ваш код неполный, следовательно, полную диагностику дать невозможно.
Но в любом случае перебирать карту здесь нет смысла. Просто используйте
public static Boolean checkRequestParams(Request request, String[] keys) {
Map<?,?> params = JsonUtil.fromJson(request.body(), HashMap.class);
for(String key: keys) {
if (params.get(key) == null) return false;
}
return true;
}
Это гарантирует, что каждый ключ присутствует и не отображается на null (поскольку «не сопоставление с null» уже подразумевает присутствие).
Если не рассматривать возможность явного сопоставления с null, вы можете проверить наличие всех ключей так же просто, как
public static Boolean checkRequestParams(Request request, String[] keys) {
Map<?,?> params = JsonUtil.fromJson(request.body(), HashMap.class);
return params.keySet().containsAll(Arrays.asList(keys));
}
В качестве альтернативы вы можете считать карту недействительной, если какое-либо сопоставленное значение равно null, даже если ее ключ не является одним из обязательных ключей. Тогда это было бы так же просто, как
public static Boolean checkRequestParams(Request request, String[] keys) {
Map<?,?> params = JsonUtil.fromJson(request.body(), HashMap.class);
return params.keySet().containsAll(Arrays.asList(keys))
&& !params.values().contains(null);
}
Есть ли причина, по которой вы используете
getValue(), а неgetKey()?