有人建议我使用#view.attributes
地图存储view scoped data that I need to survive even after session destroys(保存客户端状态)。现在它完全符合我的要求,但我只是想确保这不是一个坏习惯或坏事。
我发现这与viewcope map的工作方式完全相同,只是在用户会话被销毁后,它仍能保存数据。
答案 0 :(得分:3)
在2.0之前的JSF版本中,只能使用UIViewRoot.set / getAttribute在视图中存储对象。
然而,在JSF 2.0中,引入了一个单独的视图范围,可以通过#{viewScope}在EL中使用,也可以使用UIViewRoow.getViewMap()以编程方式使用。建议使用视图范围。它使用保存在UIViewRoot中的Map实现,并以与视图状态中的视图属性相同的方式进行序列化,因此它与视图属性具有相同的生命周期。
<强>更新强>
来自MyFaces团队的Leonardo Uribe表示:
在JSF 2.2中,决定将视图范围bean始终存储在会话中 (看看@ViewScoped注释中的描述 的javadoc)。但是你可以调用facesContext.getViewRoot()并使用 属性图。只需记住必须有Serializable或的值 实现StateHolder。
所以看起来可移植的方法是使用UIViewRoot中的属性映射。
答案 1 :(得分:0)
viewScope
。避免使用视图根(一般组件)属性有两个原因:
理论上,您可能会覆盖视图根组件属性。在实践中,由于属性键是用enum
(至少在mojarra中)实现的,因此无法实现
UIComponentBase.getAttributes
返回特定的Map
实施:AttributesMap
。首先,此实现检查组件中是否存在具有相同map密钥名称的方法。如果不是,它会检查内部地图。如果再次找不到它,它会检查组件ValueExpression
地图。因此它根本没有效率,并且在非常特殊的情况下,可以导致无限递归。
请查看AttributesMap.get
,例如:
public Object get(Object keyObj) {
String key = (String) keyObj;
Object result = null;
if (key == null) {
throw new NullPointerException();
}
if (ATTRIBUTES_THAT_ARE_SET_KEY.equals(key)) {
result = component.getStateHelper().get(UIComponent.PropertyKeysPrivate.attributesThatAreSet);
}
Map<String,Object> attributes = (Map<String,Object>)
component.getStateHelper().get(PropertyKeys.attributes);
if (null == result) {
PropertyDescriptor pd =
getPropertyDescriptor(key);
if (pd != null) {
try {
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
result = (readMethod.invoke(component,
EMPTY_OBJECT_ARRAY));
} else {
throw new IllegalArgumentException(key);
}
} catch (IllegalAccessException e) {
throw new FacesException(e);
} catch (InvocationTargetException e) {
throw new FacesException(e.getTargetException());
}
} else if (attributes != null) {
if (attributes.containsKey(key)) {
result = attributes.get(key);
}
}
}
if (null == result) {
ValueExpression ve = component.getValueExpression(key);
if (ve != null) {
try {
result = ve.getValue(component.getFacesContext().getELContext());
} catch (ELException e) {
throw new FacesException(e);
}
}
}
return result;
}
考虑到你的必要条件,至少从webapp的角度来看,这没有多大意义。视图状态记住组件状态:从初始状态更改并将在下一步处理的组件模型值。如果这些值不被处理,则不需要长时间记录。我们可以认为它们是“短暂的”。相反,如果必须长时间处理和记住它们,就必须坚持不懈。事实上,我不能认为这种数据的单一案例能够比会话存活更长时间,而且比永久性更短(持久性)。
你能告诉我们一个现实生活中的例子吗?
我脑海中最好的例子是记住tabView或手风琴的活动索引,但是这个值可以(并且应该)保留,如果它很重要的话。
但是每个问题都有一个解决方案,我能想到的第一件事就是你可以实现一个自定义范围,它使用特定的cookie(客户端)值作为关键字将这些值存储在应用程序范围内。