英文:
How to map several json fields to a single java map?
问题
如何将此 JSON 映射到此 Java 对象,其中 habits
Map 将具有键 HabitName.FITNESS
和 HabitName.MATHEMATICS
以及相应的值?构造函数、getter 和 setter 方法已被省略以提高可读性。
public class IncomingJson {
Map<HabitName, HabitDesc> habits;
public enum HabitName {
@JsonProperty("fitness") FITNESS,
@JsonProperty("mathematics") MATHEMATICS
}
public static class HabitDesc {
String duration;
String score;
}
}
运行时,我收到以下异常:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "fitness" (class IncomingJson), not marked as ignorable (one known property: "habits")
请注意,你提供的JSON中使用了HTML实体编码,所以在代码中应该使用普通的双引号 "fitness"
和 "mathematics"
而不是 "fitness"
和 "mathematics"
。如果你的JSON中确实包含了HTML实体编码,需要在反序列化时先将其解码为普通字符串。
英文:
How to map this JSON to this Java object where the habits
Map will have the keys HabitName.FITNESS
and HabitName.MATHEMATICS
with the corresponding values? Constructor, getters and setters are omitted to readability.
{
"habits": {
"fitness": {
"duration": "1 week",
"score": "2.1"
},
"mathematics": {
"duration": "2 weeks",
"score": "2.4"
}
}
}
public class IncomingJson {
Map<HabitName, HabitDesc> habits;
public enum HabitName {
@JsonProperty("fitness") FITNESS,
@JsonProperty("mathematics") MATHEMATICS
}
public static class HabitDesc {
String duration;
String score;
}
}
At runtime I get the following Exception:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "fitness" (class IncomingJson), not marked as ignorable (one known property: "habits")
答案1
得分: 0
解决方案已经接近了。您可以轻松将此JSON反序列化为以下Java类。
@Getter
@RequiredArgsConstructor
@JsonRootName("root")
public class Habits {
private final Map<HabitName, HabitDesc> habits = new HashMap<>();
public enum HabitName {
@JsonProperty("fitness") FITNESS,
@JsonProperty("mathematics") MATHEMATICS
}
@Getter
@RequiredArgsConstructor
public static class HabitDesc {
@JsonProperty("duration") private final String duration;
@JsonProperty("score") private final String score;
}
}
重要提示: 上述类依赖于lombok.config
文件中的lombok.anyconstructor.addconstructorproperties=true
,该文件位于与Habits.class
相同的包中。
因此,您的反序列化代码将如下所示:
var objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
Habits habits = objectMapper.readValue(JSON_STRING, Habits.class);
英文:
The solution was close. You can deserialize this JSON into the following Java class easily.
{
"root" : {
"habits": {
"fitness": {
"duration": "1 week",
"score": "2.1"
},
"mathematics": {
"duration": "2 weeks",
"score": "2.4"
}
}
}
}
@Getter
@RequiredArgsConstructor
@JsonRootName("root")
publi class Habits {
private final Map<HabitName, HabitDesc> habits = new HashMap<>();
public enum HabitName {
@JsonProperty("fitness") FITNESS,
@JsonProperty("mathematics") MATHEMATICS
}
@Getter
@RequiredArgsConstructor
public static class HabitDesc {
@JsonProperty("duration") private final String duration;
@JsonProperty("score") private final String score;
}
}
IMPORTANT: The above class relies on lombok.anyconstructor.addconstructorproperties=true
in the lombok.config file in the same package as Habits.class.
So your deserialization code will look like this
var objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
Habits = objectMapper.readValue(JSON_STRING, Habits.class);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论