2017-02-16 8 views
3

Вот простой Java-код, чтобы проверить мой вопрос:Weird 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); 

Теперь вы можете увидеть из JSON, что мы должны иметь 2 администратора счета и счета объекта является правильно, но у организации только первая. Вот скриншот значений в отладчике: From debugger

У кого-нибудь есть идеи, откуда это может произойти?

+0

Как AdminAccount (или что-то называется классом) 's равно/хэш-код реализован? Я заметил, что у обоих учетных записей есть пустой идентификатор. Если равенство учетной записи основано на id, то HashSet (правильно) опустит ее как дубликат. – yshavit

+0

@yshavit Это не реализовано в классе Account, и я считаю, что это также будет действительным для набора «учетных записей», который имеет (правильно) оба элемента. – grekier

+0

А, хороший момент. Как выглядит один элемент в adminAccount? Означает ли это какое-либо представление о том, что происходит? – yshavit

ответ

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); 

В принципе, ваша строка s представляет счета и jsonBody, представленный организацией. Попытайтесь создать эти два учетных поля в первую очередь и организуйте их и манипулируйте ими как объекты java.

0

Вот код, который я тестировал, чтобы заставить его работать. Я использую jackson-databind-2.8.6. Я подозреваю, что есть что-то странное с классами POJO или может быть ошибка в версии Джексона вы используете:

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 = «[ object1] ", а object1 имеет два элемента, поэтому accounts.size() = 2, organization.adminAccounts = s =" [object1] ", organization.adminAccounts.size() = 1, organization.adminAccounts имеет только объект1. Вы хотите, чтобы организация.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

Смежные вопросы