How to use Jackson to deserialise an array of objects

JavaJsonJackson

Java Problem Overview


The Jackson data binding documentation indicates that Jackson supports deserialising "Arrays of all supported types" but I can't figure out the exact syntax for this.

For a single object I would do this:

//json input
{
    "id" : "junk",
    "stuff" : "things"
}

//Java
MyClass instance = objectMapper.readValue(json, MyClass.class);

Now for an array I want to do this:

//json input
[{    "id" : "junk",    "stuff" : "things"},{    "id" : "spam",    "stuff" : "eggs"}]

//Java
List<MyClass> entries = ?

Anyone know if there is a magic missing command? If not then what is the solution?

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

From Eugene Tskhovrebov

List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class))

This solution seems to be the best for me.

Solution 3 - Java

For Generic Implementation:

public static <T> List<T> parseJsonArray(String json,
                                         Class<T> classOnWhichArrayIsDefined) 
                                         throws IOException, ClassNotFoundException {
   ObjectMapper mapper = new ObjectMapper();
   Class<T[]> arrayClass = (Class<T[]>) Class.forName("[L" + classOnWhichArrayIsDefined.getName() + ";");
   T[] objects = mapper.readValue(json, arrayClass);
   return Arrays.asList(objects);
}

Solution 4 - Java

First create an instance of ObjectReader which is thread-safe.

ObjectMapper objectMapper = new ObjectMapper();
ObjectReader objectReader = objectMapper.reader().forType(new TypeReference<List<MyClass>>(){});

Then use it :

List<MyClass> result = objectReader.readValue(inputStream);

Solution 5 - Java

try this

List<MyClass> list = mapper.readerForListOf(MyClass.class).readValue(json)

Solution 6 - Java

try {
	ObjectMapper mapper = new ObjectMapper();
	JsonFactory f = new JsonFactory();
	List<User> lstUser = null;
	JsonParser jp = f.createJsonParser(new File("C:\\maven\\user.json"));
	TypeReference<List<User>> tRef = new TypeReference<List<User>>() {};
	lstUser = mapper.readValue(jp, tRef);
	for (User user : lstUser) {
		System.out.println(user.toString());
	}
	
} catch (JsonGenerationException e) {
	e.printStackTrace();
} catch (JsonMappingException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

Solution 7 - Java

I was unable to use this answer because my linter won't allow unchecked casts.

Here is an alternative you can use. I feel it is actually a cleaner solution.

public <T> List<T> parseJsonArray(String json, Class<T> clazz) throws JsonProcessingException {
  var tree = objectMapper.readTree(json);
  var list = new ArrayList<T>();
  for (JsonNode jsonNode : tree) {
    list.add(objectMapper.treeToValue(jsonNode, clazz));
  }
  return list;
}

Solution 8 - Java

here is an utility which is up to transform json2object or Object2json, whatever your pojo (entity T)

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

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * 
 * @author TIAGO.MEDICI
 * 
 */
public class JsonUtils {

	public static boolean isJSONValid(String jsonInString) {
		try {
			final ObjectMapper mapper = new ObjectMapper();
			mapper.readTree(jsonInString);
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	public static String serializeAsJsonString(Object object) throws JsonGenerationException, JsonMappingException, IOException {
		ObjectMapper objMapper = new ObjectMapper();
		objMapper.enable(SerializationFeature.INDENT_OUTPUT);
		objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		StringWriter sw = new StringWriter();
		objMapper.writeValue(sw, object);
		return sw.toString();
	}

	public static String serializeAsJsonString(Object object, boolean indent) throws JsonGenerationException, JsonMappingException, IOException {
		ObjectMapper objMapper = new ObjectMapper();
		if (indent == true) {
			objMapper.enable(SerializationFeature.INDENT_OUTPUT);
			objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		}

		StringWriter stringWriter = new StringWriter();
		objMapper.writeValue(stringWriter, object);
		return stringWriter.toString();
	}

	public static <T> T jsonStringToObject(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
		T obj = null;
		ObjectMapper objMapper = new ObjectMapper();
		obj = objMapper.readValue(content, clazz);
		return obj;
	}

	@SuppressWarnings("rawtypes")
	public static <T> T jsonStringToObjectArray(String content) throws JsonParseException, JsonMappingException, IOException {
		T obj = null;
		ObjectMapper mapper = new ObjectMapper();
		obj = mapper.readValue(content, new TypeReference<List>() {
		});
		return obj;
	}

	public static <T> T jsonStringToObjectArray(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
		T obj = null;
		ObjectMapper mapper = new ObjectMapper();
		mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
		obj = mapper.readValue(content, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
		return obj;
	}

Solution 9 - Java

you could also create a class which extends ArrayList:

public static class MyList extends ArrayList<Myclass> {}

and then use it like:

List<MyClass> list = objectMapper.readValue(json, MyList.class);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOllie EdwardsView Question on Stackoverflow
Solution 1 - JavaProgrammer BruceView Answer on Stackoverflow
Solution 2 - JavaMarthymView Answer on Stackoverflow
Solution 3 - JavaPallav JhaView Answer on Stackoverflow
Solution 4 - JavaGreg DView Answer on Stackoverflow
Solution 5 - Javahantian_pangView Answer on Stackoverflow
Solution 6 - JavajeromeView Answer on Stackoverflow
Solution 7 - JavalbenedettoView Answer on Stackoverflow
Solution 8 - JavaTiago MediciView Answer on Stackoverflow
Solution 9 - Javapero_heroView Answer on Stackoverflow