使用 JPA 加载一些数据后,我在更新会话属性时遇到问题。
我设置/获取会话属性:
request.getSession().setAttribute("user", user);
User user = (User) request.getSession().getAttribute("user");
在应用程序的某个地方,我从数据库加载列表users
(与user
会话属性相同),修改并保存。一切都会好起来的,我将获得最新信息,但如果我从会话属性中获取信息,则不会。我不想为几乎静态的信息请求数据库,但另一方面我不知道如何更新会话属性。
存储会话的属性可能是非常不正确的实现吗?
更新 这个解决方案怎么样:
我有会话属性的缓存
public static final HashMap<String, HashMap<String, Object>> sessionAttributeMaps = new HashMap<>();
public static final HashMap<String, HashMap<String, Object>> sessionAttributeMapsForUpdate = new HashMap<>();
在sessionAttributeMaps
我存储会话属性(我需要稍后刷新并保持实际),使用HttpSessionAttributeListener
:
@WebListener
public class SessionAttributeListener implements HttpSessionAttributeListener{
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
String SessionId = event.getSession().getId();
String attributeName = event.getName();
Object attributeValue = event.getValue();
if (attributeName.equalsIgnoreCase("user")) {
HashMap<String, Object> hm = ServletUtil.sessionAttributeMaps.get(SessionId);
if (hm==null) {
hm = new HashMap<String, Object>();
ServletUtil.sessionAttributeMaps.put(SessionId, hm);
}
hm.put("user", attributeValue);
}
}
...
}
sessionAttributeMaps(用于几个创建的会话):
[[会话1:[{“user”:user1},{“customer”:customer1}]],
[会话 2: [{"user" : user1}, {"customer" : customer2}]],
[会话 3: [{"user" : user2}, {"customer" : customer1}]] ]
在sessionAttributeMapsForUpdate
我存储会话属性的实际值(当它们被改变时,我在地图中检查它在 POJO 实体中实现的所有会话)。
public void fireChanges() {
for (Entry<String, HashMap<String, Object>> sessionAttributesMap : servlets.ServletUtil.sessionAttributeMaps.entrySet()) {
for (Entry<String, Object> entry : sessionAttributesMap.getValue().entrySet()) {
if (this.equals(entry.getValue()) && this!=entry.getValue()) {
entry.setValue(this);
HashMap<String, Object> hm = ServletUtil.sessionAttributeMapsForUpdate.get(sessionAttributesMap.getKey());
if (hm==null) {
hm = new HashMap<String, Object>();
ServletUtil.sessionAttributeMapsForUpdate.put(sessionAttributesMap.getKey(), hm);
}
hm.put("user", this);
}
}
}
}
如果user1
更改,我填写sessionAttributeMapsForUpdate
:
[[会话1:[{“user”:user1}]],
[会话 2: [{"user" : user1}]]]
在助手中,我获取会话属性并检查更新(使用更新的清洁)
public static Object getSessionAttribute(String key) {
Object value = FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
if (key.equalsIgnoreCase("user")) {
if (!ServletUtil.sessionAttributeMapsForUpdate.isEmpty()) {
HttpSession hs = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
HashMap<String, Object> hm = ServletUtil.sessionAttributeMapsForUpdate.get(hs.getId());
if (hm!=null) {
User u = (User) hm.get("user");
if (u!=null) {
value = u;
removeSessionAttribute("user");
setSessionAttribute("user", value);
hm.remove("user");
}
if (hm.isEmpty()) {
ServletUtil.sessionAttributeMapsForUpdate.remove(hs.getId());
}
}
}
}
return value;
}
警告:由于新等于(但是) ,setSessionAttribute("user", value);
因此无法正常工作removeSessionAttribute("user");
value
value from session map
!=
因此,当我使用助手获取会话属性时,我使用实际值。
可能已经有像我这样但经过时间考验的解决方案?