In your case, I would write a custom JsonDeserializer. Haven't really tested the code, but I think the idea is clear:

    final MyClassDeserializer myClassDeserializer = new MyClassDeserializer();
    final SimpleModule deserializerModule = new SimpleModule();
    deserializerModule.addDeserializer(MyClass.class, myClassDeserializer);

    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(deserializerModule);

And the code for JsonDeserializer:

    public class MyClassDeserializer extends JsonDeserializer<MyClass> {

    @Override
    public MyClass deserialize(final JsonParser jsonParser, final DeserializationContext context)
            throws IOException {
        final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        final JsonNode sourcesNode = node.get("sources");
        if(node.isArray()) {
            final ArrayNode arrayNode = (ArrayNode) node;
            final Iterable<JsonNode> nodes = arrayNode::elements;
            final Set<Source> set = StreamSupport.stream(nodes.spliterator(), false)
                    .map(mapper)
                    .collect(Collectors.toSet());
            ...
        }

        ...
    }
Answer from yyunikov on Stack Overflow
🌐
Fasterxml
fasterxml.github.io › jackson-databind › javadoc › 2.7 › com › fasterxml › jackson › databind › ObjectMapper.html
ObjectMapper (jackson-databind 2.7.0 API)
public <T> T readValue(JsonParser jp, TypeReference<?> valueTypeRef) throws IOException, JsonParseException, JsonMappingException
🌐
Baeldung
baeldung.com › home › json › jackson › intro to the jackson objectmapper
Intro to the Jackson ObjectMapper | Baeldung
December 9, 2025 - String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]"; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true); Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class); // print cars
🌐
Javadoc.io
javadoc.io › doc › com.fasterxml.jackson.core › jackson-databind › 2.3.1 › com › fasterxml › jackson › databind › ObjectMapper.html
ObjectMapper - jackson-databind 2.3.1 javadoc
Bookmarks · Latest version of com.fasterxml.jackson.core:jackson-databind · https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind · Current version 2.3.1 · https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/2.3.1 · package-list path (used for javadoc generation ...
Top answer
1 of 3
2

In your case, I would write a custom JsonDeserializer. Haven't really tested the code, but I think the idea is clear:

    final MyClassDeserializer myClassDeserializer = new MyClassDeserializer();
    final SimpleModule deserializerModule = new SimpleModule();
    deserializerModule.addDeserializer(MyClass.class, myClassDeserializer);

    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(deserializerModule);

And the code for JsonDeserializer:

    public class MyClassDeserializer extends JsonDeserializer<MyClass> {

    @Override
    public MyClass deserialize(final JsonParser jsonParser, final DeserializationContext context)
            throws IOException {
        final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        final JsonNode sourcesNode = node.get("sources");
        if(node.isArray()) {
            final ArrayNode arrayNode = (ArrayNode) node;
            final Iterable<JsonNode> nodes = arrayNode::elements;
            final Set<Source> set = StreamSupport.stream(nodes.spliterator(), false)
                    .map(mapper)
                    .collect(Collectors.toSet());
            ...
        }

        ...
    }
2 of 3
0

First thing: Your JSON is invalid. There is a comma after the second object in the sources array. This has to be deleted.

Second: I think you didn't choose the right type for your result. What your JSON represents is a map which maps from string to an array of objects. So the type should be something like Map<String, Props[]> (Since you didn't provide the name of your class, I called it Props.

With these considerations you can construct a MapType by using ObjectMappers getTypeFactory() method and deserialize the value using the constructed type like shown below.

ObjectMapper mapper = new ObjectMapper();
TypeFactory typeFactory = mapper.getTypeFactory();
MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, Props[].class);
Map<String, Props[]> map = mapper.readValue(s, mapType);
🌐
Jenkov
jenkov.com › tutorials › java-json › jackson-objectmapper.html
Jackson ObjectMapper
ObjectMapper objectMapper = new ObjectMapper(); String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }"; try { Car car = objectMapper.readValue(carJson, Car.class); System.out.println("car brand = " + car.getBrand()); System.out.println("car doors = " + car.getDoors()); } catch (IOException e) { e.printStackTrace(); }
🌐
Northcoder
northcoder.com › post › jackson-object-mapper-which-way-is
Jackson's ObjectMapper and TypeReference | northCoder
Some notes on Jackson’s ObjectMapper, when using it without any custom POJO classes, to deserialize an arbitrary piece of JSON to a Java Map.
🌐
Adobe Developer
developer.adobe.com › experience-manager › reference-materials › cloud-service › javadoc › com › fasterxml › jackson › databind › ObjectMapper.html
ObjectMapper (The Adobe Experience Manager SDK 2022.11.9850.20221116T162329Z-220900)
Note that although most read and write methods are exposed through this class, some of the functionality is only exposed via ObjectReader and ObjectWriter: specifically, reading/writing of longer sequences of values is only available through ObjectReader.readValues(InputStream) and ObjectWriter.writeValues(OutputStream). Simplest usage is of form: final ObjectMapper mapper = new ObjectMapper(); // can use static singleton, inject: just make sure to reuse!
Find elsewhere
🌐
Fasterxml
fasterxml.github.io › jackson-databind › javadoc › 2.8 › com › fasterxml › jackson › databind › ObjectMapper.html
ObjectMapper (jackson-databind 2.8.0 API)
public <T> T readValue(JsonParser p, TypeReference<?> valueTypeRef) throws IOException, JsonParseException, JsonMappingException
🌐
GitHub
github.com › FasterXML › jackson-databind › issues › 3301
`ObjectMapper.readValue()` from `java.io.File` fails to parse single quoted string (json5) · Issue #3301 · FasterXML/jackson-databind
October 13, 2021 - Describe the bug com.fasterxml.jackson.databind.ObjectMapper.readValue drops double quotes when parsing *.json5 file. (specifically, when parsing a single quoted string value) Version information 2.12.4 · To Reproduce ·
Author   wcarmon
🌐
Medium
medium.com › @salvipriya97 › java-objectmapper-explained-c33cdc4876d1
Java ObjectMapper explained. In Java, an object mapper is a tool… | by Priya Salvi | Medium
April 21, 2024 - In this example, we use the readValue() method of ObjectMapper to convert the JSON string into a Person object.
🌐
Spring Framework Guru
springframework.guru › home › how to the jackson object mapper with json
How to The Jackson Object Mapper with JSON - Spring Framework Guru
October 22, 2024 - Introduction As a Java developer, a common task you'll encounter is converting between Java objects and JSON. The Jackson library is a powerful and widely used tool for this purpose. Whether you're building RESTful APIs, microservices, or simply handling JSON data in your application, Jackson's ObjectMapper class makes it easy to serialize and deserialize Java
🌐
Medium
medium.com › @salvipriya97 › objectmapper-and-its-methods-examples-in-java-4a4cab75cb6b
ObjectMapper and its methods examples in Java | by Priya Salvi | Medium
June 25, 2024 - import com.fasterxml.jackson.databind.ObjectMapper; public class Main { public static void main(String[] args) { String json = "{\"name\":\"John\", \"age\":30}"; ObjectMapper objectMapper = new ObjectMapper(); try { Person person = objectMapper.readValue(json, Person.class); System.out.println(person.getName()); // Output: John } catch (Exception e) { e.printStackTrace(); } } }
🌐
Baeldung
baeldung.com › home › json › jackson › deserialize generic type with jackson
Deserialize Generic Type with Jackson | Baeldung
September 17, 2025 - JavaType javaType = objectMapper.getTypeFactory().constructParametricType(JsonResponse.class, User.class); JsonResponse<User> jsonResponse = objectMapper.readValue(json, javaType);
🌐
GitHub
github.com › FasterXML › jackson-databind › issues › 778
IOException might not be necessary for readValue(String content, Class<T> valueType) · Issue #778 · FasterXML/jackson-databind
May 1, 2015 - Hi guys, At present ObjectMapper#readValue(String content, Class valueType) declares IOException. I don't see when an IOException can happen while working with in-memory strings. If this is not really need can we discuss removing it? It'...
Author   ihr
🌐
Reflectoring
reflectoring.io › jackson
All You Need To Know About JSON Parsing With Jackson
July 15, 2022 - ObjectMapper is the most commonly ... com.fasterxml.jackson.databind. The readValue() method is used to parse (deserialize) JSON from a String, Stream, or File into POJOs....
🌐
Index.dev
index.dev › blog › deserialize-json-java-mapper
How to Deserialize JSON in Java Using a Mapper | Index.dev
January 28, 2025 - import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.databind.DeserializationFeature; import java.util.List; public class UserDeserializer { // Thread-safe ObjectMapper configured for production use private static final ObjectMapper objectMapper = new ObjectMapper() .registerModule(new JavaTimeModule()) // Handle Java 8 date/time types .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); public static User deseri