- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我对注册自定义 KeyDeserializer
的工作原理感到困惑。
这是我的代码:
package com.example;
import java.io.Serializable;
import java.util.Objects;
public class Matchday implements Serializable, Comparable<Matchday> {
private static final long serialVersionUID = -8823049187525703664L;
private final int matchdayNumber;
public Matchday(final int matchdayNumber) {
this.matchdayNumber = matchdayNumber;
}
public int getMatchdayNumber() {
return matchdayNumber;
}
@Override
public int compareTo(Matchday o) {
return Integer.compare(matchdayNumber, o.getMatchdayNumber());
}
@Override
public final int hashCode() {
return Objects.hash(matchdayNumber);
}
@Override
public final boolean equals(final Object obj) {
return obj instanceof Matchday && Integer.valueOf(matchdayNumber).equals(((Matchday) obj).matchdayNumber);
}
@Override
public String toString() {
return Integer.toString(matchdayNumber);
}
}
package com.example;
import java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder;
public class TeamPlayer implements Serializable {
private static final long serialVersionUID = -6057852081020631549L;
private int id;
private String name;
private String surname;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
@Override
public String toString() {
return new ToStringBuilder(this).append("id", id).append("name", name).append("surname", surname).build()
.toString();
}
}
现在,如果我为我的 Matchday.java 类定义一个自定义 map 键反序列化器,如果我这样做,它就会像魅力一样工作。
package com.example;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.SortedMap;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class KeyDeserializerTest {
public static void main(String[] args) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
final SimpleModule mySimpleModule = new SimpleModule("dummy", new Version(0, 0, 0, "dummy", "dummy", "dummy"));
mySimpleModule.addKeyDeserializer(Matchday.class, new KeyDeserializer() {
@Override
public Object deserializeKey(String arg0, DeserializationContext arg1)
throws IOException, JsonProcessingException {
return new Matchday(Integer.valueOf(arg0));
}
});
objectMapper.registerModule(mySimpleModule);
final InputStream inputStream = new ByteArrayInputStream(
"{\"1\":[{\"id\": 1, \"name\": \"Arkadiusz\", \"surname\": \"Malarz\"}]}".getBytes());
SortedMap<Matchday, List<TeamPlayer>> map = objectMapper.readValue(inputStream,
new TypeReference<SortedMap<Matchday, List<TeamPlayer>>>() {
});
System.out.println(map);
}
}
打印
{1=[com.example.TeamPlayer@3a8624[id=1,name=Arkadiusz,surname=Malarz]]}
但是如果我将对象映射器和反序列化器实例都定义为静态属性,那么我会得到以下异常!
package com.example;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.SortedMap;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class KeyDeserializerStaticTest {
public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
private static final KeyDeserializer MATCHDAY_KEY_DESERIALIZER = new KeyDeserializer() {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return new Matchday(Integer.valueOf(key));
}
};
private static ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(createSimpleModule());
return objectMapper;
}
private static Module createSimpleModule() {
SimpleModule simpleModule = new SimpleModule("dummy", new Version(0, 0, 0, "dummy", "dummy", "dummy"));
simpleModule.addKeyDeserializer(Matchday.class, MATCHDAY_KEY_DESERIALIZER);
return simpleModule;
}
public static void main(String[] args) throws IOException {
final InputStream inputStream = new ByteArrayInputStream(
"{\"1\":[{\"id\": 1, \"name\": \"Arkadiusz\", \"surname\": \"Malarz\"}]}".getBytes());
SortedMap<Matchday, List<TeamPlayer>> map = OBJECT_MAPPER.readValue(inputStream,
new TypeReference<SortedMap<Matchday, List<TeamPlayer>>>() {
});
System.out.println(map);
}
}
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.example.Matchday]
at [Source: java.io.ByteArrayInputStream@bbc1e0; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:585)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:168)
at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:499)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:247)
at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:681)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:481)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3899)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3794)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2915)
at com.example.KeyDeserializerStaticTest.main(KeyDeserializerStaticTest.java:43)
这里出了什么问题?从语义上讲,上述主要方法之间没有区别。这是一个已记录在案的功能还是只是 Jackson 中的一个错误?
最佳答案
这里的根本问题是静态变量的初始化顺序。
是
public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
private static final KeyDeserializer MATCHDAY_KEY_DESERIALIZER = new KeyDeserializer() {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return new Matchday(Integer.valueOf(key));
}
};
虽然应该如此
private static final KeyDeserializer MATCHDAY_KEY_DESERIALIZER = new KeyDeserializer() {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return new Matchday(Integer.valueOf(key));
}
};
public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
这很难发现,因为方法 addKeyDeserializer(Class<?>, KeyDeserializer)
类(class)SimpleModule
默默地添加null
对内部键反序列化器映射的引用。在我看来,它应该抛出 NullPointerException
尝试添加关键解串器引用 null
.
它的 Jackson 代码如下所示。
第一addKeKeyDeserializer(Class<?>, KeyDeserializer)
public SimpleModule addKeyDeserializer(Class<?> type, KeyDeserializer deser)
{
if (_keyDeserializers == null) {
_keyDeserializers = new SimpleKeyDeserializers();
}
_keyDeserializers.addDeserializer(type, deser);
return this;
}
这里没有检查是否 deser
是 null
.
然后它委托(delegate)给类SimpleKeyDeserializers
的addDeserializer(Class, KeyDeserializer) .
public SimpleKeyDeserializers addDeserializer(Class<?> forClass, KeyDeserializer deser)
{
if (_classMappings == null) {
_classMappings = new HashMap<ClassKey,KeyDeserializer>();
}
_classMappings.put(new ClassKey(forClass), deser);
return this;
}
这是 null
引用也被忽略并默默地放入 _classMappings
map 。
Here是我在 GitHub 上发布的问题以及讨论。
关于java - 找不到静态定义的 KeyDeserializer,但如果在本地定义,一切都很完美,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40523287/
例如,我有一个父类Author: class Author { String name static hasMany = [ fiction: Book,
代码如下: dojo.query(subNav.navClass).forEach(function(node, index, arr){ if(dojo.style(node, 'd
我有一个带有 Id 和姓名的学生表和一个带有 Id 和 friend Id 的 Friends 表。我想加入这两个表并找到学生的 friend 。 例如,Ashley 的 friend 是 Saman
我通过互联网浏览,但仍未找到问题的答案。应该很容易: class Parent { String name Child child } 当我有一个 child 对象时,如何获得它的 paren
我正在尝试创建一个以 Firebase 作为我的后端的社交应用。现在我正面临如何(在哪里?)找到 friend 功能的问题。 我有每个用户的邮件地址。 我可以访问用户的电话也预订。 在传统的后端中,我
我主要想澄清以下几点: 1。有人告诉我,在 iOS 5 及以下版本中,如果您使用 Game Center 设置多人游戏,则“查找 Facebook 好友”(如与好友争夺战)的功能不是内置的,因此您需要
关于redis docker镜像ENTRYPOINT脚本 docker-entrypoint.sh : #!/bin/sh set -e # first arg is `-f` or `--some-
我是一名优秀的程序员,十分优秀!