HashTable getcontainsKey не работает
Я не понимаю, почему этот простой метод не работает
Мои занятия AccessChecker
имеет атрибут Hashtable<String, List<Permission>> permissions = new Hashtable<String, List<Permission>>();
двумя способами:
Первый способ
Если я поставлю this.permissions.containsKey(key)
в конце этого метода, с хорошим ключом, он работает.
public void updatePermissions() {
List<Permission> permissionsTmp = permissionRepository.findAllWithEagerRelationships();
// clear permissions
this.permissions = new Hashtable<>();
// load all permissions
for (Permission permission : permissionsTmp) {
Profil profil = profilRepository.findOne(permission.getProfil().getId());
permission.setProfil(profil);
UserFonc user = userFoncRepository.findOne(permission.getUserFonc().getId());
permission.setUserFonc(user);
log.error("updatePermissions ** user login = " + user.getNom());
for (WebService webService: profil.getWebServices()) {
String key = createKeyPermissions(user.getNom().toLowerCase(), webService.getNom(), webService.getMethode());
log.error("updatePermissions ** key = " + key);
if (this.permissions.containsKey(key)){
this.permissions.get(key).add(permission);
}
else {
List<Permission> newPermissions = new ArrayList<>();
newPermissions.add(permission);
this.permissions.put(key, newPermissions);
}
}
}
}
Второй метод
Но когда я делаю это в методе hasAccessToWebservice()
, это не работает для того же ключа...
public boolean hasAccessToWebservice(HttpServletRequest request) {
boolean hasAccess = false;
String webservice = getServiceFromRequest(request);
String methode = request.getMethod();
String login = SecurityUtils.getCurrentUserLogin();
String userAgent = request.getHeader(Constants.USER_AGENT);
final String userLogin = SecurityUtils.getCurrentUserLogin();
log.error("hasAccessToWebservice ** user login = " + userLogin);
String key = createKeyPermissions(login.toLowerCase(), webservice, methode);
log.error("hasAccessToWebservice ** key = " + key);
log.error("hasAccessToWebservice ** element = " + this.permissions.size());
Set t = this.permissions.keySet();
log.error(t.toString());
if (this.permissions.containsKey(key)) {
log.error("hasAccessToWebservice ** key found !!");
hasAccess = true;
}
return hasAccess;
}
Вы можете объяснить, почему?
Спасибо
2 ответа
Краткое описание проблемы
Чтобы подвести итог темы, проблема вращалась вокруг ключевой последовательности:
Map.containsKey(Object key)
будет в основном проверять, еслиkey
является одним изMap.keySet()
в основном полагаясь наObject.hashCode()
Ваш ключевой класс карты
String
, Если вы посмотрите наString.hashCode()
код, вы увидите, что он опирается на каждое значение символа.Возвращает хеш-код для этой строки. Хеш-код для объекта String вычисляется как
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
используя int арифметику, где s [i] - это i-й символ строки, n - длина строки, а ^ - возведение в степень. (Значение хеша пустой строки равно нулю.)
Значение можно найти в таблице ASCII, подчеркнув, что
hashCode()
чувствителен к регистру
Решение / Улучшение
- Самое простое решение - убедиться, что
createKeyPermissions
метод всегда выдает согласованный ключ для интерфейса, помещая все в нижний регистр - Использовать
TreeMap
с компаратором, где наиболее подходящийString.CASE_INSENSITIVE_ORDER
Вам нужно вызвать updatePermissions, чтобы поместить все данные в ваши разрешения перед запуском hasAccessToWebservice
Если вы запускаете hasAccessToWebservice без updatePermissions, у вас ничего нет в списке разрешений => this.permissions.containsKey(ключ) не работает