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 ответа

Решение

Краткое описание проблемы

Чтобы подвести итог темы, проблема вращалась вокруг ключевой последовательности:

  1. Map.containsKey(Object key) будет в основном проверять, если key является одним из Map.keySet() в основном полагаясь на Object.hashCode()
  2. Ваш ключевой класс карты 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(ключ) не работает

Другие вопросы по тегам