如何将多个 json 字段映射到单个 java 映射?

How to map several json fields to a single java map?

如何将此 JSON 映射到此 Java 对象,其中 habits 映射将具有具有相应值的键 HabitName.FITNESSHabitName.MATHEMATICS?为了便于阅读,省略了构造函数、getter 和 setter。

{
  "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;
  }
}

在运行时我得到以下异常:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "fitness" (class IncomingJson), not marked as ignorable (one known property: "habits") 

解决方案很接近。您可以轻松地将此 JSON 反序列化为以下 Java class。

{
    "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;
    }
}

重要:上面的class依赖于lombok.config文件中的lombok.anyconstructor.addconstructorproperties=trueHabits.class.

相同的包

因此您的反序列化代码将如下所示

var objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
Habits = objectMapper.readValue(JSON_STRING, Habits.class);