Jackson 不会映射到自定义的侦听器映射对象?
Jackson won't map to a customized listener map object?
所以我一直在开发一个小的 LinkedHashMap 扩展 class 用于我的一个项目,我在其中编辑它以在 put
方法中有一个值更改侦听器。这是我的地图 class:
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;
}
}
问题是,我正在尝试将对象映射到此映射 class 的实例,其中:
ObjectMapper mapper = new ObjectMapper();
MapWithListeners<String, Object> map = mapper.convertValue(mainObj, new TypeReference<MapWithListeners<String, Object>>() {
});
结果是一张空地图。我试过只用一个普通的 LinkedHashMap 来做这件事,它主要按照我需要的方式工作,但它失去了我也需要的值变化监听器。我假设我在我的 MapWithListeners class 中做错了什么,但无法弄清楚那是什么。
在此先感谢您对此的任何帮助!
编辑:我发现有必要将我的静态 class 更改为抽象 class,基本上是这样的:
abstract class MapWithListeners<K,V> extends LinkedHashMap<K,V> implements Map<K,V>
然后使用抽象类型映射模块配置我的映射器,例如:
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]]
有什么想法吗?
只需尝试以下操作:通过构建自定义 MapType
为 Jackson 映射器提供更多类型支持。此后,您可以使用它进行转换。
我已经实施了以下内容并且它起到了作用,你 post 中提到的 IllegalArgumentException
消失了:
MapType javaType = mapper.getTypeFactory().constructMapType(MapWithListeners.class, String.class, Object.class);
MapWithListeners<String, Object> map = mapper.convertValue(mainObj, javaType);
所以我一直在开发一个小的 LinkedHashMap 扩展 class 用于我的一个项目,我在其中编辑它以在 put
方法中有一个值更改侦听器。这是我的地图 class:
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;
}
}
问题是,我正在尝试将对象映射到此映射 class 的实例,其中:
ObjectMapper mapper = new ObjectMapper();
MapWithListeners<String, Object> map = mapper.convertValue(mainObj, new TypeReference<MapWithListeners<String, Object>>() {
});
结果是一张空地图。我试过只用一个普通的 LinkedHashMap 来做这件事,它主要按照我需要的方式工作,但它失去了我也需要的值变化监听器。我假设我在我的 MapWithListeners class 中做错了什么,但无法弄清楚那是什么。 在此先感谢您对此的任何帮助!
编辑:我发现有必要将我的静态 class 更改为抽象 class,基本上是这样的:
abstract class MapWithListeners<K,V> extends LinkedHashMap<K,V> implements Map<K,V>
然后使用抽象类型映射模块配置我的映射器,例如:
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]]
有什么想法吗?
只需尝试以下操作:通过构建自定义 MapType
为 Jackson 映射器提供更多类型支持。此后,您可以使用它进行转换。
我已经实施了以下内容并且它起到了作用,你 post 中提到的 IllegalArgumentException
消失了:
MapType javaType = mapper.getTypeFactory().constructMapType(MapWithListeners.class, String.class, Object.class);
MapWithListeners<String, Object> map = mapper.convertValue(mainObj, javaType);