Deserialize JSON to ArrayListPOJO using Jackson
You can deserialize directly to a list by using the TypeReference
wrapper. An example method:
public static <T> T fromJSON(final TypeReference<T> type,
final String jsonPacket) {
T data = null;
try {
data = new ObjectMapper().readValue(jsonPacket, type);
} catch (Exception e) {
// Handle the problem
}
return data;
}
And is used thus:
final String json = "";
Set<POJO> properties = fromJSON(new TypeReference<Set<POJO>>() {}, json);
TypeReference Javadoc
How to use Jackson to deserialise an array of objects
First create a mapper :
import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3
ObjectMapper mapper = new ObjectMapper();
As Array:
MyClass[] myObjects = mapper.readValue(json, MyClass[].class);
As List:
List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
Another way to specify the List type:
List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));
Deserialize JSON array to a single Java object with Jackson
Thanks to bureaquete for suggestion to use custom Deserializer. But it was more suitable for me to register it with SimpleModule
instead of @JsonDeserialize
annotation. Below is complete JUnit test example:
@RunWith(JUnit4.class)
public class MapArrayToObjectTest {
private static ObjectMapper mapper;
@BeforeClass
public static void setUp() {
mapper = new ObjectMapper();
SimpleModule customModule = new SimpleModule("ExampleModule", new Version(0, 1, 0, null));
customModule.addDeserializer(Person.class, new PersonDeserializer());
mapper.registerModule(customModule);
}
@Test
public void wrapperDeserializationTest() throws IOException {
//language=JSON
final String inputJson = "{\"persons\": [[\"John\", \"Doe\"], [\"Jane\", \"Doe\"]]}";
PersonsListWrapper deserializedList = mapper.readValue(inputJson, PersonsListWrapper.class);
assertThat(deserializedList.persons.get(0).lastName, is(equalTo("Doe")));
assertThat(deserializedList.persons.get(1).firstName, is(equalTo("Jane")));
}
@Test
public void listDeserializationTest() throws IOException {
//language=JSON
final String inputJson = "[[\"John\", \"Doe\"], [\"Jane\", \"Doe\"]]";
List<Person> deserializedList = mapper.readValue(inputJson, mapper.getTypeFactory().constructCollectionType(List.class, Person.class));
assertThat(deserializedList.get(0).lastName, is(equalTo("Doe")));
assertThat(deserializedList.get(1).firstName, is(equalTo("Jane")));
}
}
class PersonsListWrapper {
public List<Person> persons;
}
class Person {
final String firstName;
final String lastName;
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
class PersonDeserializer extends JsonDeserializer<Person> {
@Override
public Person deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode node = jp.readValueAsTree();
return new Person(node.get(0).getTextValue(), node.get(1).getTextValue());
}
}
Note that if you do not need wrapper object, you can deserialize JSON array[["John", "Doe"], ["Jane", "Doe"]]
directly to List<Person>
using mapper as follows:
List<Person> deserializedList = mapper.readValue(inputJson, mapper.getTypeFactory().constructCollectionType(List.class, Person.class));
How to deserialize a json array followed by a normal property into a pojo in jackson. The array alone works
The solution is a deserializer, because the type handling is very difficult in this case. The deserializer decide between the two cases, array or the single last value, and call in the case of an array the deserializer for the CandleStick
Class:
public class OhlcDeserializer extends JsonDeserializer<OhclPayload> {
@Override
public OhclPayload deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
List<CandleStick> candleSticks = new ArrayList<CandleStick>();
Long last = null;
ObjectCodec objectCodec = p.getCodec();
JsonNode jsonNode = objectCodec.readTree(p);
Iterator<Entry<String, JsonNode>> payloadIterator = jsonNode.fields();
while (payloadIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = payloadIterator.next();
if (entry.getKey().equals("last")) {
last = entry.getValue().asLong();
} else if (entry.getValue().isArray()) {
for (JsonNode node : entry.getValue()) {
CandleStick cs = p.getCodec().treeToValue(node, CandleStick.class);
candleSticks.add(cs);
}
}
}
return new OhclPayload(candleSticks, last);
}
}
I changed the OhclResponse to:
public class OhlcResponse extends Response<OhclPayload> {
}
And insert a OhlcPayload class for the deserializer:
@JsonDeserialize(using = OhlcDeserializer.class)
public class OhclPayload {
private List<CandleStick> candleSticks;
private Long last;
// getters and setters
}
Thats all.
Deserialize a json array to objects using Jackson and WebClient
For the response to be matched with AccountOrderList
class, json has to be like this
{
"accountOrders": [
{
"symbol": "XRPETH",
"orderId": 12122,
"clientOrderId": "xxx",
"price": "0.00000000",
"origQty": "25.00000000",
"executedQty": "25.00000000",
"status": "FILLED",
"timeInForce": "GTC",
"type": "MARKET",
"side": "BUY",
"stopPrice": "0.00000000",
"icebergQty": "0.00000000",
"time": 1514558190255,
"isWorking": true
},
{
"symbol": "XRPETH",
"orderId": 1212,
"clientOrderId": "xxx",
"price": "0.00280000",
"origQty": "24.00000000",
"executedQty": "24.00000000",
"status": "FILLED",
"timeInForce": "GTC",
"type": "LIMIT",
"side": "SELL",
"stopPrice": "0.00000000",
"icebergQty": "0.00000000",
"time": 1514640491287,
"isWorking": true
},
....
]
}
This is what the error message says "out of START_ARRAY token"
If you cannot change the response, then change your code to accept Array like this
this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON)
.retrieve().bodyToMono(AccountOrder[].class).log();
You can convert this array to List and then return.
JSON deserialize ArrayList correctly
First issue: you are deserializing to ArrayList without any generic type, because of this you are receiving ArrayList of LinkedHashMap. Jackson doesn't know that you are wanting list of person, so it uses LinkedHashMap as type applicable to any json.
To deserialize to list of person you should use:
ArrayList<Person> list = mapper.readValue(new FileInputStream("./person.json"),
mapper.getTypeFactory().constructCollectionType(ArrayList.class, Person.class));
Second issues: that you are working with Java 8 time (LocalDate class), but Jackson doesn't know about it. To be able to handle it properly, you need to add JavaTimeModule
from jackson-datatype-jsr310
dependency and register it.
So resulting code will be like this:
public void write() {
ArrayList<Person> personList = new ArrayList<>();
Person p1 = new Person("James", "Bond", LocalDate.of(1997, 9, 22));
Person p2 = new Person("Santa", "Claus", LocalDate.of(1918, 11, 6));
Person p3 = new Person("Peter", "Griffin", LocalDate.of(1978, 3, 24));
Person p4 = new Person("Lois", "Griffin", LocalDate.of(1982, 7, 14));
personList.add(p1);
personList.add(p2);
personList.add(p3);
personList.add(p4);
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());
try {
writer.writeValue(new File("./person.json"), personList);
} catch (IOException e) {
e.printStackTrace();
}
}
public void read() {
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
try {
ArrayList<Person> list = mapper.readValue(new FileInputStream("./person.json"),
mapper.getTypeFactory().constructCollectionType(ArrayList.class, Person.class));
System.out.println("Read: " + list.get(0).getFirstname());
} catch (IOException e) {
e.printStackTrace();
}
}
Map JsonArray to ListPojo using Jackson ObjectMapper
You can use the TypeFactory to create a CollectionLikeType.
For example like this:
ObjectMapper objectMapper = new ObjectMapper();
CollectionLikeType collectionLikeType = objectMapper.getTypeFactory()
.constructCollectionLikeType(List.class, String.class);
List<String> o = objectMapper.readValue("[\"hello\"]", collectionLikeType);
assertEquals(o, List.of("hello"));
Related Topics
Java/Convert Iso-8601 (2010-12-16T13:33:50.513852Z) to Date Object
Directly Convert CSV File to JSON File Using the Jackson Library
How to Set Up Java Logging Using a Properties File? (Java.Util.Logging)
Variable Naming Conventions in Java
Using Java Map for Range Searches
Class.Getresource() Returns Null
Running Java in Package from Command Line
How to Set Auto-Scrolling of Jtextarea in Java Gui
Compare One String with Multiple Values in One Expression
What Is the Priority of Casting in Java
How to Tell If a Checkbox Is Selected in Selenium for Java
How to Wait Until an Element Is Present in Selenium
Nullpointerexception Through Auto-Boxing-Behavior of Java Ternary Operator
Hexadecimal to Integer in Java
"Non-Static Variable This Cannot Be Referenced from a Static Context" When Creating an Object