0

我不明白为什么这个简单的方法不起作用

我的班级有两个方法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;
}

你能解释一下为什么吗?

谢谢

4

2 回答 2

1

问题总结

总结主题,问题围绕关键一致性:

  1. Map.containsKey(Object key)基本上会检查是否keyMap.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最简单的解决方案是通过将所有内容都放在小写字母的接口来确保方法始终生成一致的密钥
  • 将 aTreeMap与最适合的比较器一起使用String.CASE_INSENSITIVE_ORDER
于 2017-10-06T08:56:47.417 回答
1

在运行 hasAccessToWebservice 之前,您需要调用 updatePermissions 将所有数据放入您的权限中

如果您在没有 updatePermissions 的情况下运行 hasAccessToWebservice,则权限列表中没有任何内容 => this.permissions.containsKey(key) 不起作用

于 2017-10-05T16:05:09.163 回答