2017-02-16 25 views
3

下面是一個簡單的Java代碼來測試我的問題:與集怪異的JSON映射的問題 - 缺少的元素

ObjectMapper mapper = new ObjectMapper(); 
String s = "[\n" + 
      " {\n" + 
      "  \"id\": \"\",\n" + 
      "  \"name\": \"fsgh\",\n" + 
      "  \"email\": \"[email protected]\",\n" + 
      "  \"password\": \"fdg\"\n" + 
      " },\n" + 
      " {\n" + 
      "  \"id\": \"\",\n" + 
      "  \"name\": \"sdfg\",\n" + 
      "  \"email\": \"[email protected]\",\n" + 
      "  \"password\": \"dfghfgh\"\n" + 
      " }\n" + 
      " ]"; 
String jsonBody = "{\n" + 
      " \"id\": \"\",\n" + 
      " \"name\": \"<cxzzx\",\n" + 
      " \"email\": \"[email protected]\",\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); 

現在,你可以從我們應該有2個管理員帳戶和帳戶對象是JSON看正確的,但該組織只有第一個。以下是調試器中的值的屏幕截圖: From debugger

任何人有任何想法可能來自哪裏?

+0

如何AdminAccount(或任何類的叫法)的等號/的hashCode實現?我注意到兩個帳戶都有一個空的ID。如果一個帳戶的平等是基於id的,那麼HashSet將(正確)忽略一個副本。 – yshavit

+0

@yshavit它沒有在Account類中實現,我相信這也適用於「帳戶」設置,它已經(正確)有兩個元素 – grekier

+0

啊,好點。 adminAccount中的一個元素是什麼樣的?它是否提供了關於發生了什麼的線索? – yshavit

回答

0

我強烈建議你不要使用字符串連接,因爲傑克遜提供了實現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對象

0

這是我測試的代碼,以便使其工作。我正在使用jackson-databind-2.8.6。我懷疑有一些奇怪的事情與你的POJO類或有可能是傑克遜的版本的bug,使用:

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\": \"[email protected]\",\n" + 
     "  \"password\": \"fdg\"\n" + 
     " },\n" + 
     " {\n" + 
     "  \"id\": \"\",\n" + 
     "  \"name\": \"sdfg\",\n" + 
     "  \"email\": \"[email protected]\",\n" + 
     "  \"password\": \"dfghfgh\"\n" + 
     " }\n" + 
     " ]"; 
     final String jsonBody = "{\n" + 
     " \"id\": \"\",\n" + 
     " \"name\": \"<cxzzx\",\n" + 
     " \"email\": \"[email protected]\",\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; 
    } 
} 
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\": \"[email protected]\",\n" + 
     "  \"password\": \"fdg\"\n" + 
     " }],\n" + 
     " [{\n" + 
     "  \"id\": \"\",\n" + 
     "  \"name\": \"sdfg\",\n" + 
     "  \"email\": \"[email protected]\",\n" + 
     "  \"password\": \"dfghfgh\"\n" + 
     " }]\n" + 
     " ]"; 

enter image description here