我正在尝试使用 jackson 并使用以下混合从 json 标量字符串反序列化来自 Threetenextra 库的 YearWeek:
import org.threeten.extra.YearWeek;
import com.fasterxml.jackson.annotation.JsonCreator;
public class YearWeekMixIn {
@JsonCreator
public static YearWeek parse(String value) {
return YearWeek.parse(value);
}
}
但是以下测试失败:
public class YearWeekMixInTest {
public record Foo(YearWeek yearWeek) {}
@Test
public void foo() throws JsonMappingException, JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(YearWeek.class, YearWeekMixIn.class);
objectMapper.readValue("{\"yearWeek\": \"2011-W01\"}", Foo.class);
}
}
我收到以下异常:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造
的实例(不存在创建者,如默认构造函数):没有从字符串值反序列化的字符串参数构造函数/工厂方法('2011-W01' )org.threeten.extra.YearWeek
mixin 中缺少什么来让 jackson 知道它应该使用 mixin 中带注释的方法进行反序列化?
jackson 的 mixin 不支持工厂方法。 所以我认为它还有另外两个解决方案供您使用。
解决方案1(使用StdConverter,且无需配置ObjectMapper)
class YearWeekConverter extends StdConverter<String, YearWeek> {
@Override
public YearWeek convert(String s) {
return YearWeek.parse(s);
}
}
record Foo(@JsonDeserialize(converter = YearWeekConverter.class) YearWeek yearWeek) {}
解决方案2(使用StdDeserializer)
class YearWeekDeserializer extends StdDeserializer<YearWeek> {
public YearWeekDeserializer() {
this(null);
}
public YearWeekDeserializer(Class<?> vc) {
super(vc);
}
@Override
public YearWeek deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
final String s = jp.readValueAs(String.class);
return YearWeek.parse(s);
}
}
public class YearWeekMixInTest {
public record Foo(YearWeek yearWeek) {}
@Test
public void foo() throws JsonMappingException, JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(YearWeek.class, YearWeekMixIn.class);
// add module
SimpleModule module = new SimpleModule();
module.addDeserializer(YearWeek.class, new YearWeekDeserializer());
objectMapper.registerModule(module);
objectMapper.readValue("{\"yearWeek\": \"2011-W01\"}", Foo.class);
}
}