I don't understand why this simple method does not work
My class AccessChecker has the attribute Hashtable<String, List<Permission>> permissions = new Hashtable<String, List<Permission>>(); with two methods:
First method
If I put this.permissions.containsKey(key) at the end of this method , with a good key, it works.
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);
}
}
}
}
Second method
But, when I do this in method hasAccessToWebservice(), it does NOT work for the same key...
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;
}
Can you explain why?
Thank you
Problem summary
To summarise the topic, the problem revolved around the key consistency:
Map.containsKey(Object key)will basically check ifkeyis among theMap.keySet()mainly by relying onObject.hashCode()Your map key class is
String. If you look atString.hashCode()code, you'll see that it relies on each single character value.Value can be found in the ASCII Table highlighting that
hashCode()is case-sensitiveSolution / Improvement
createKeyPermissionsmethod always produces consistent key by for interface putting everything in lowercaseTreeMapwith a comparator where the most fitted one isString.CASE_INSENSITIVE_ORDER