2015-06-02 1 views
0

Почему я не могу десериализовать массив объектов, развернув корневой узел?Почему я не могу развернуть корневой узел и десериализовать массив объектов?

import java.io.IOException; 
import java.util.Arrays; 
import java.util.List; 

import org.codehaus.jackson.map.DeserializationConfig; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.codehaus.jackson.map.annotate.JsonRootName; 
import org.junit.Assert; 
import org.junit.Test; 

public class RootNodeTest extends Assert { 

    @JsonRootName("customers") 
    public static class Customer { 
     public String email; 
    } 

    @Test 
    public void testUnwrapping() throws IOException { 
     String json = "{\"customers\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}"; 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
     List<Customer> customers = Arrays.asList(mapper.readValue(json, Customer[].class)); 
     System.out.println(customers); 
    } 
} 

Я копаться в документации Джексона, и это то, что я мог понять, но после запуска, я получаю следующее сообщение об ошибке:

A org.codehaus.jackson.map.JsonMappingException has been caught, Root name 'customers' does not match expected ('Customer[]') for type [array type, component type: [simple type, class tests.RootNodeTest$Customer]] at [Source: [email protected]; line: 1, column: 2] 

Я хотел бы сделать это без создания класс оболочки. Хотя это пример, я не хочу создавать ненужные классы-оболочки только для развертывания корневого узла.

+0

удалите скобки массива из второго параметра при попытке прочитатьValue и поместите их в переменную электронной почты. Преобразователь преобразует значение json String в объект типа Customer и затем сопоставляет эти письма в массив. –

+0

@ArthurEirich Я не мог совсем последовать. Не могли бы вы привести пример? –

+0

см. Мой ответ, я понял это –

ответ

5

Создать ObjectReader настроить корневое имя в явном виде :

@Test 
public void testUnwrapping() throws IOException { 
    String json = "{\"customers\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}"; 
    ObjectReader objectReader = mapper.reader(new TypeReference<List<Customer>>() {}) 
             .withRootName("customers"); 
    List<Customer> customers = objectReader.readValue(json); 
    assertThat(customers, contains(customer("[email protected]"), customer("[email protected]"))); 
} 

(? кстати, это с Джексоном 2.5, у вас есть другая версия у меня есть DeserializationFeature, а не DeserializationConfig.Feature)

кажется, что с помощью устройства чтения объекта я В этом случае вам не нужно глобально настраивать функцию «развернуть значение корня» или использовать аннотацию @JsonRootName.

Заметим также, что вы можете непосредственно запросить List<Customer>, а не через array- тип предоставленный ObjectMapper.reader работ так же, как второй параметр для ObjectMapper.readValue

+0

Это получилось просто. Я использовал старый импорт «codehaus». Теперь я переключился на 'quickxml'. Причина, по которой я использую нотацию массива вместо typereference, поскольку абстрактные классы отображаются, когда они открываются, когда я запускаю Corbertura. –

-1

кажется, что вы не можете избежать класса-оболочки. согласно this, то @JsonRootName аннотацию только позволит вам разворачивать в JSON, который содержит один экземпляр вашей POJO: поэтому он будет работать на строку, как это: "{\"customer\":{\"email\":\"[email protected]\"}}";

-1

Этот код работал для меня:

import org.codehaus.jackson.map.ObjectMapper; 
import org.junit.Assert; 
import org.junit.Test; 

import java.io.IOException; 
import java.util.List; 

public class RootNodeTest extends Assert { 

public static class CustomerMapping { 
    public List<Customer> customer; 

    public List<Customer> getCustomer() { 
     return customer; 
    } 

    public static class Customer { 
     public String email; 

     public String getEmail() { 
      return email; 
     } 
    } 

} 

@Test 
public void testUnwrapping() throws IOException { 
    String json = "{\"customer\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}"; 
    ObjectMapper mapper = new ObjectMapper(); 
    CustomerMapping customerMapping = mapper.readValue(json, CustomerMapping.class); 
    List<CustomerMapping.Customer> customers = customerMapping.getCustomer(); 
    for (CustomerMapping.Customer customer : customers) { 
     System.out.println(customer.getEmail()); 
    } 
    } 
} 

Прежде всего вам нужен Java-объект для всего json-объекта. В моем случае это CustomerMapping. Тогда вам нужен объект java для вашего ключа клиента. В моем случае это внутренний класс CustomerMapping.Customer. Поскольку клиент - это json-массив, вам нужен список объектов CustomerMapping.Customer. Кроме того, вам не нужно отображать массив json в массив java и преобразовывать его в список. Джексон уже делает это за вас. Наконец, вы просто укажете переменную электронной почты типа String и распечатаете ее на консоли.

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