【问题标题】:Jackson won't map to a customized listener map object?Jackson 不会映射到自定义的侦听器映射对象?
【发布时间】:2021-05-02 20:59:11
【问题描述】:

因此,我一直在开发一个小型 LinkedHashMap 扩展类以用于我的一个项目,我在其中对其进行了编辑,以便在 put 方法中拥有一个值更改侦听器。这是我的地图类:

    static class MapWithListeners<K, V> extends LinkedHashMap<K, V> {
        private final LinkedHashMap<K, V> delegate;
        public static final String UPDATE_EVT = "update";

        public MapWithListeners() {
            this.delegate = new LinkedHashMap<>();
        }

        public MapWithListeners(LinkedHashMap<K, V> delegate) {
            this.delegate = delegate;
        }

        private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            changeSupport.addPropertyChangeListener(listener);
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
            changeSupport.removePropertyChangeListener(listener);
        }

        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
            changeSupport.firePropertyChange(propertyName, oldValue, newValue);
        }

        @Override
        public V put(K var1, V var2) {
            V oldValue = delegate.put(var1, var2);
            firePropertyChange(UPDATE_EVT, oldValue == null ? null : new AbstractMap.SimpleEntry<>(var1, oldValue),
                               new AbstractMap.SimpleEntry<>(var1, var2));
            return oldValue;
        }
    }

问题是,我试图将一个对象映射到这个地图类的一个实例:

ObjectMapper mapper = new ObjectMapper();
MapWithListeners<String, Object> map = mapper.convertValue(mainObj, new TypeReference<MapWithListeners<String, Object>>() {
        });

结果是一张空地图。我已经尝试仅使用常规 LinkedHashMap 来执行此操作,并且它主要以我需要的方式工作,但是它失去了我也需要的值更改侦听器。我假设我在 MapWithListeners 类中做错了什么,但无法弄清楚那是什么。 提前感谢您对此的任何帮助!

编辑:我发现有必要将我的静态类更改为抽象类,基本上就像: abstract class MapWithListeners&lt;K,V&gt; extends LinkedHashMap&lt;K,V&gt; implements Map&lt;K,V&gt;

然后使用抽象类型映射模块配置我的映射器,例如:

SimpleModule module = new SimpleModule().addAbstractTypeMapping(Map.class, MapWithListeners.class);
mapper.registerModule(module);

然而,走到这一步却在convertValue 行返回了一个错误,上面写着:

java.lang.IllegalArgumentException: Cannot find a deserializer for non-concrete Map type [map type; class com.invoiceeditor.POJOEditor$MapWithListeners, [simple type, class java.lang.String] -> [simple type, class java.lang.Object]]

有什么想法吗?

【问题讨论】:

    标签: java jackson hashmap listener linkedhashmap


    【解决方案1】:

    只需尝试以下操作:通过构建自定义 MapType,为 Jackson 映射器提供更多类型支持。此后,您可以使用它进行转换。

    我已经实现了以下内容,它成功了,您帖子中提到的IllegalArgumentException 消失了:

    MapType javaType = mapper.getTypeFactory().constructMapType(MapWithListeners.class, String.class, Object.class);
    MapWithListeners<String, Object> map = mapper.convertValue(mainObj, javaType);
    
    

    【讨论】:

    • 所以我实际上在我悬赏之后就找到了这个问题的正确答案。似乎我应该从一开始就实现 map 及其方法,并坚持使用linkedhashmapo 作为委托。既然您是第一个发表评论的人,请获得赏金!
    猜你喜欢
    • 2012-07-08
    • 2015-12-23
    • 1970-01-01
    • 2012-12-31
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多