我使用弹簧靴2,弹簧安全性。我为用户创建缓存。在我的用户类中,我有一个语言字段:FR,EN...允许用户选择他们想要的语言 UI。
实际上,用户可以更改它的lang。
@EnableCaching
public class CacheConfig {
@Bean
public UserCache userCache() throws Exception {
return new SpringCacheBasedUserCache(new ConcurrentMapCache("userCache"));
}
}
public class I18nLocaleResolver extends SessionLocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && !"anonymousUser".equals(auth.getPrincipal())) {
CustomUserDetails user = (CustomUserDetails) auth.getPrincipal();
String lang = user.getLang();
if (lang == null) {
lang = LanguagesEnum.FR.getLanguage();
}
Locale locale = new Locale(lang);
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
return locale;
}
Locale locale = (Locale) WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);
if (locale == null) {
locale = determineDefaultLocale(request);
}
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
}
}
In UserDetailsServiceImpl
@Transactional
@Override
public void updateLang(Integer userId, String newLanguage) {
Optional<Users> optUserApp = repository.findById(userId);
if (!optUserApp.isPresent()) {
throw new UsernameNotFoundException("Username id " + userId + " not found");
}
Users user = optUserApp.get();
user.setLang(newLanguage);
repository.save(user);
userCache.removeUserFromCache(user.getUsername());
}
场景
用户 lang 是 EN,所以它为 FR 更改它,我们通过 updateLang 方法传递,更改它在数据库端完成,调试器后转到 I18nLocaleResolver。在这个地方,看到的是旧值(EN(。有没有办法在没有注销用户的情况下刷新它?
某些缓存实现可能不支持从缓存中逐出,在这种情况下,它们应提供适当的行为,以通过异常或日志消息在其文档中更改用户。
SpringCacheBasedUserCache
请尝试传递用户对象而不是用户名。如果要更新缓存中的用户,也请尝试putUserInCache(user)
此方法