如果我们按照原来的方式来反序列化record(如果字段上没有@JsonProperty注解的话),会直接报错: InvalidDefinitionException: Cannot construct instance of Person (no Creators, like default construct, exist)
这是因为jackson没法找到构造函数和字段的映射,所以我们自己指定默认的映射:
1 2 3 4 5 6 7 8 9 10 11 12 13
// from https://gist.github.com/youribonnaffe/03176be516c0ed06828ccc7d6c1724ce JacksonAnnotationIntrospectorimplicitRecordAI=newJacksonAnnotationIntrospector() { @Override public String findImplicitPropertyName(AnnotatedMember m) { if (m.getDeclaringClass().isRecord()) { if (m instanceof AnnotatedParameter parameter) { return m.getDeclaringClass().getRecordComponents()[parameter.getIndex()].getName(); } } returnsuper.findImplicitPropertyName(m); } }; objectMapper.setAnnotationIntrospector(implicitRecordAI);
publicstaticvoidmain(String[] args)throws IOException { ObjectMapperobjectMapper=newObjectMapper(); // get default propertyName from record // thanks youribonnaffe JacksonAnnotationIntrospectorimplicitRecordAI=newJacksonAnnotationIntrospector() { @Override public String findImplicitPropertyName(AnnotatedMember m) { if (m.getDeclaringClass().isRecord()) { if (m instanceof AnnotatedParameter parameter) { return m.getDeclaringClass().getRecordComponents()[parameter.getIndex()].getName(); } if (m instanceof AnnotatedMember member) { for (RecordComponent recordComponent : m.getDeclaringClass().getRecordComponents()) { if (recordComponent.getName().equals(member.getName())) { return member.getName(); } } } } returnsuper.findImplicitPropertyName(m); } }; objectMapper.setAnnotationIntrospector(implicitRecordAI); StringjsonStr=""" { "id":1, "name":"name1", "alias": "alias1,alias2", "password": "password1" } """; Personperson= objectMapper.readValue(jsonStr, Person.class); System.out.println(person); // Person[id=1, name=name1, alias=[alias1, alias2], password=password1] StringjsonOut= objectMapper.writeValueAsString(person); System.out.println(jsonOut); // {"alias":"alias1,alias2","id":1,"name":"name1"} }
/** * convert String to List, just for field alias * <p> * this is class-bound logic, so keep it internal */ staticclassAliasConverterextendsStdConverter<String, List<String>> { @Override public List<String> convert(String value) { return Arrays.stream(value.split(",")).collect(Collectors.toList()); } } }