【问题标题】:Java controller getting only first item from Set via JSONJava 控制器通过 JSON 仅从 Set 中获取第一项
【发布时间】:2018-12-20 14:39:03
【问题描述】:

试图保存一对多 JPA 关系。我写了一个自定义控制器。我只得到giftSet 中的第一个id,而不是所有的id。我已经简化了代码。

我的帖子请求-

{
  "name": "Project 7",
  "giftSet": [
    {
        "id": "1"
    },
    {
        "id":"33"
    }
  ]
}

class Holiday{
  private String name;
  private Set<GiftConfig> giftSets;
}

class GiftSet {
  private Integer id;
  private Holiday holiday;
}

class GiftConfig {
  private Integer id;
  private String name;
}

@RequestMapping(method = RequestMethod.POST, value="/api/saveholiday")
public ResponseEntity<Map<String, Holiday>> saveHoliday(@RequestBody Holiday holiday) {
  System.out.println(holiday);
  return null;
}

首先,我添加了多个 GiftConfig。之后,在创建 Holiday 时,我还添加了 GiftSet 的详细信息。

在调试模式下,我在 giftSet 中只看到 id 1 而不是 id 1 和 33。 注意 - 更改设置为列表不是一种选择。

【问题讨论】:

  • 你能发布完整的GiftSet类吗?有equals()/hashCode() 实现吗?
  • 没有 equals()/hashCode() 实现。我将 Lombok 用于 Getter 和 Setter。
  • 我更新了代码。非常抱歉,我忘了加一门课。
  • 如果您使用 Lombok,GiftSet 类是否使用任何 Lombok 注释进行注释?
  • @Kedar 如果您使用的是 lambok,则需要包含您的 lambok 注释。例如。 @Data,或@Setters@Getters。在我的回答中,我确实包括了它们并且一切正常。新年快乐!

标签: java json spring-boot jackson


【解决方案1】:

简介

我看到 2 个问题和一个可能的最后一个问题。

  1. 您缺少 setter/getter 以便反序列化对 JSON 起作用。
  2. 您的有效负载似乎不适合我。

正如 pcoates 在评论中提到的,您也可以使用 @JsonAutoDetect(fieldVisibility = Visibility.ANY) - 但我还没有对此进行测试。

最后,如果你从 java 转换回 JSON,也要小心循环引用。我看到一个假期有一组giftSet,但是一个giftSet 指向一个假期。 如果 gitset 指向同一个父节假日,这是循环引用,会崩溃。

Getter 和 Setter

您的问题是您缺少 getter 和 setter。 使用 lombok 并添加 @data 注释或添加 getter 和 setter。

@Data
    public  static class Holiday{
        private String name;
        private Set<GiftSet> giftSets;
    }

    @Data
    public static class  GiftSet {
        private Integer id;
        private Holiday holiday;
    }

有效载荷

我使用了以下负载:

{
  "name": "HolidaySet",
  "giftSets": [
    {
      "id": 1111,
      "holiday": {
        "name": null,
        "giftSets": null
      }
    },
    {
      "id": 1112,
      "holiday": {
        "name": null,
        "giftSets": null
      }
    }
  ]
}

快速测试

我做了一个快速测试,看看负载应该是什么样子。

@RequestMapping(method = RequestMethod.POST, value="/api/saveholiday")
    public ResponseEntity<Map<String, Holiday>> saveHoliday(@RequestBody Holiday holiday) throws JsonProcessingException {
        System.out.println(holiday);

        fakeItTest();

        return null;
    }

    private void fakeItTest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();

        Set<GiftSet> giftSets2 = new HashSet<>();
        GiftSet gg = new GiftSet();
        gg.setId(1111);
        gg.setHoliday(new Holiday());
        giftSets2.add(gg);

        GiftSet gg2 = new GiftSet();
        gg2.setId(1112);
        gg2.setHoliday(new Holiday());
        giftSets2.add(gg2);

        Holiday holiday2 = new Holiday();
        holiday2.setName("HolidaySet");
        holiday2.setGiftSets(giftSets2);

        String a = objectMapper.writeValueAsString(holiday2);
        System.out.println(a);
    }


    @Data
    public  static class Holiday{
        private String name;
        private Set<GiftSet> giftSets;
    }

    @Data
    public static class  GiftSet {
        private Integer id;
        private Holiday holiday;
    }

【讨论】:

  • Setter 和 getter 不是强制性的。您可以将 Jackson 配置为使用字段。例如在课堂上使用 @JsonAutoDetect(fieldVisibility = Visibility.ANY) 。也可以在全球范围内完成。
  • @pcoates 是的,这是真的。虽然 AFAK,但它并不常用。
  • 我已经在使用 Lombok,因此没有 getter 和 setter。你觉得我哪里错了?
  • 我更新了代码。非常抱歉,我忘了加一门课。
  • @Kedar 我的解决方案将起作用,您只需在某些 中将 giftSet 更改为 giftConfig 即可。我看到的一个问题是您缺少 @Data lambok 注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多