针对具有静态WeakHashMap的通用JSF对象转换器的参数

时间:2015-05-12 09:29:58

标签: jsf jsf-2 converter

我想避免使用样板代码来创建SelectItems列表以在视图和模型之间映射我的实体/ dtos,所以我使用了通用对象转换器的snippet

@FacesConverter(value = "objectConverter")
public class ObjectConverter implements Converter {

private static Map<Object, String> entities = new WeakHashMap<Object, String>();

@Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
    synchronized (entities) {
        if (!entities.containsKey(entity)) {
            String uuid = UUID.randomUUID().toString();
            entities.put(entity, uuid);
            return uuid;
        } else {
            return entities.get(entity);
        }
    }
}

@Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
    for (Entry<Object, String> entry : entities.entrySet()) {
        if (entry.getValue().equals(uuid)) {
            return entry.getKey();
        }
    }
    return null;
}

}

已经有很多answers个问题,但我想要一个香草解决方案(没有*面孔)。以下几点仍然让我对我的片段质量不确定:

  1. 如果这很容易,为什么没有将通用对象转换器构建到JSF
  2. 为什么这么多人仍在使用SelectItems?使用通用方法不是更灵活吗?例如。 #{dto.label}可以快速更改为#{dto.otherLabel}。
  3. 鉴于范围只是在视图和模型之间进行映射,通用方法是否有任何重大缺点?

1 个答案:

答案 0 :(得分:6)

这种方法很麻烦,内存效率低下。

在一个小应用程序中它是“好的”,但绝对不是在一个大型应用程序中,可以在f:selectItems中引用数十或数十万个潜在实体。而且,这种大型应用程序通常具有第二级实体缓存。 WeakHashMap变得毫无用处,只有在从底层数据存储中物理移除实体(因此也从二级实体缓存中移除)时才有效。

它肯定是一个“有趣”的因素,但我真的不建议在“大量生产”中使用它。

如果您不想使用像OmniFaces SelectItemsConverter这样的实用程序库中的现有解决方案(基本上完全无状态且不使用任何DAO /服务调用),那么您最好的选择是:使用公共基接口/类抽象所有实体并将转换器挂钩。这只需要DAO / Service调用。这个问答已在本Q&amp; A:Implement converters for entities with Java Generics中详细阐述。