Set的奇怪JSON映射问题 - 缺少一个元素

时间:2017-02-16 15:14:57

标签: java json jackson pojo objectmapper

这是一个简单的Java代码来测试我的问题:

ObjectMapper mapper = new ObjectMapper();
String s = "[\n" +
            "    {\n" +
            "      \"id\": \"\",\n" +
            "      \"name\": \"fsgh\",\n" +
            "      \"email\": \"dfgh@qwe.qwe\",\n" +
            "      \"password\": \"fdg\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"\",\n" +
            "      \"name\": \"sdfg\",\n" +
            "      \"email\": \"zxc@zxc.sd\",\n" +
            "      \"password\": \"dfghfgh\"\n" +
            "    }\n" +
            "  ]";
String jsonBody = "{\n" +
            "  \"id\": \"\",\n" +
            "  \"name\": \"<cxzzx\",\n" +
            "  \"email\": \"asd@asd.com\",\n" +
            "  \"address\": \"asd 72b\",\n" +
            "  \"zip\": \"1234\",\n" +
            "  \"city\": \"Asdf\",\n" +
            "  \"country\": \"Norway\",\n" +
            "  \"enabled\": \"true\",\n" +
            "  \"quota\": \"50\",\n" +
            "  \"expires\": \"2021-04-02\",\n" +
            "  \"adminAccounts\": " +
            s +
            "}";
Set<Account> accounts = mapper.readValue(s, Set.class);
Organization organization = mapper.readValue(jsonBody, Organization.class);

现在你可以从json看到我们应该有2个管理员帐户,而且帐户对象是正确的,但组织只有第一个。以下是调试器中值的屏幕截图: From debugger

任何人都有任何想法可能来自哪里?

3 个答案:

答案 0 :(得分:0)

我强烈建议你 NOT 使用字符串连接,因为jackson提供了使用pojos实现此功能的可行性。它干净,不易出错。

首先声明帐号的pojo

public class Account {

private String id;

private String name;

private String email;

private String password;


public Account(String id, String name, String email, String password) {
    this.id = id;
    this.name = name;
    this.email = email;
    this.password = password;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}
}

然后是组织。请注意,我们在此处包含管理员帐户列表

public class Organization {

private String id;

private String email;

private String name;

private String address;

private String zip;

private String city;

private String country;

private boolean enabled;

private int quota;

private String expires;

private List<Account> adminAccounts;

public Organization(String id, String email, String name, String address, String zip, String city, String country, boolean enabled, int quota, String expires, List<Account> adminAccounts) {
    this.id = id;
    this.email = email;
    this.name = name;
    this.address = address;
    this.zip = zip;
    this.city = city;
    this.country = country;
    this.enabled = enabled;
    this.quota = quota;
    this.expires = expires;
    this.adminAccounts = adminAccounts;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public String getZip() {
    return zip;
}

public void setZip(String zip) {
    this.zip = zip;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public String getCountry() {
    return country;
}

public void setCountry(String country) {
    this.country = country;
}

public boolean isEnabled() {
    return enabled;
}

public void setEnabled(boolean enabled) {
    this.enabled = enabled;
}

public int getQuota() {
    return quota;
}

public void setQuota(int quota) {
    this.quota = quota;
}

public String getExpires() {
    return expires;
}

public void setExpires(String expires) {
    this.expires = expires;
}

public List<Account> getAdminAccounts() {
    return adminAccounts;
}

public void setAdminAccounts(List<Account> adminAccounts) {
    this.adminAccounts = adminAccounts;
}
}

然后我们来看实际的业务逻辑。您可以创建任意数量的帐户

Account account1 = new Account("1", "name1", "email1", "pass1");
Account account2 = new Account("2", "name2", "email2", "pass2");

并将它们添加到列表中

 List<Account> accounts = new ArrayList<Account>();
 accounts.add(account1);
 accounts.add(account2);

然后将它们添加到组织

Organization organization = new Organization("orgId", "orgEmail", "orgName", "orgAddress", "OrgZip", "orgCity", "orgCountry", true, 50, "2017-3-3", accounts);

基本上,您的String由帐户表示,jsonBody由组织表示。尝试首先创建这两个帐户pojos并组织并将它们作为java对象操作

答案 1 :(得分:0)

以下是我测试过的代码,以使其工作。我正在使用jackson-databind-2.8.6。我怀疑您的POJO课程有些奇怪,或者您使用的Jackson版本可能存在错误:

public class JacksonTest {

   public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
      final ObjectMapper mapper = new ObjectMapper();
      final String s = "[\n" +
         "    {\n" +
         "      \"id\": \"\",\n" +
         "      \"name\": \"fsgh\",\n" +
         "      \"email\": \"dfgh@qwe.qwe\",\n" +
         "      \"password\": \"fdg\"\n" +
         "    },\n" +
         "    {\n" +
         "      \"id\": \"\",\n" +
         "      \"name\": \"sdfg\",\n" +
         "      \"email\": \"zxc@zxc.sd\",\n" +
         "      \"password\": \"dfghfgh\"\n" +
         "    }\n" +
         "  ]";
      final String jsonBody = "{\n" +
         "  \"id\": \"\",\n" +
         "  \"name\": \"<cxzzx\",\n" +
         "  \"email\": \"asd@asd.com\",\n" +
         "  \"address\": \"asd 72b\",\n" +
         "  \"zip\": \"1234\",\n" +
         "  \"city\": \"Asdf\",\n" +
         "  \"country\": \"Norway\",\n" +
         "  \"enabled\": \"true\",\n" +
         "  \"quota\": \"50\",\n" +
         "  \"expires\": \"2021-04-02\",\n" +
         "  \"adminAccounts\": " + s +
         "}";

      final Set<Account> accounts = mapper.readValue(s, mapper.getTypeFactory().constructCollectionType(Set.class, Account.class));
      System.out.println("Accounts Size: " + accounts.size());
      System.out.println("Accounts: " + accounts);

      System.out.println();

      final Organization organization = mapper.readValue(jsonBody, Organization.class);
      System.out.println("Organization Admin Accounts Size: " + organization.adminAccounts.size());
      System.out.println("Organization Admin Accounts: " + organization.adminAccounts);
   }

   private static class Account {
      @Override
      public String toString() {
         return "Account [id=" + this.id + ", name=" + this.name + ", email=" + this.email + ", password=" + this.password + "]";
      }

      public String id, name, email, password;
   }

   private static class Organization {
      @Override
      public String toString() {
         return "Organization [id=" + this.id + ", name=" + this.name + ", email=" + this.email + ", address=" + this.address + ", zip=" +
            this.zip + ", city=" +
            this.city + ", country=" + this.country + ", enabled=" + this.enabled + ", quota=" + this.quota + ", expires=" + this.expires +
            ", adminAccounts=" +
            this.adminAccounts + "]";
      }

      public String id, name, email, address, zip, city, country, enabled, quota, expires;
      public Set<Account> adminAccounts;
   }
}

答案 2 :(得分:0)

我得到它,对于s,这个数组只有一个元素,s =“[object1]”而object1有两个元素,所以accounts.size()= 2,organization.adminAccounts = s =“[object1]” ,organization.adminAccounts.size()= 1,organization.adminAccounts只有object1。你想要organization.adminAccounts.size()= 2,organization.adminAccounts =“[[object2],[object3]]”,所以s =“[[object2],[object3]]”。  你可以试试这个:

String s = "[\n" +
      "    [{\n" +
      "      \"id\": \"\",\n" +
      "      \"name\": \"fsgh\",\n" +
      "      \"email\": \"dfgh@qwe.qwe\",\n" +
      "      \"password\": \"fdg\"\n" +
      "    }],\n" +
      "    [{\n" +
      "      \"id\": \"\",\n" +
      "      \"name\": \"sdfg\",\n" +
      "      \"email\": \"zxc@zxc.sd\",\n" +
      "      \"password\": \"dfghfgh\"\n" +
      "    }]\n" +
      "  ]";

enter image description here