Solving the puzzle of complex polymorphic object model deserialization in Java Jackson: Facing the JsonMappingException error – Unexpected token (START_OBJECT) instead

I am working with a hierarchy of objects described as follows:

A

B extends A

C extends B

D extends B

E extends C

F extends A and contains a reference to A

The annotation for class A is defined as:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,include=JsonTypeInfo.As.PROPERTY,property="@class")

When trying to deserialize a JSON array containing objects that extend class A, an error is thrown:

org.codehaus.jackson.map.JsonMappingException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.util.Collection)

The JSON string is generated using the toString() method of a Set parametrized to type A. The serialization of A into JSON is achieved through the following code:

ObjectMapper objectMapper=new ObjectMapper();
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS);
        String res="";
        try {
            res = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(t);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;

The code used to deserialize the JSON array (representing the aforementioned Set) is:

ObjectMapper mapper = new ObjectMapper(); 

        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS);
        Collection<T> results=null;
        try {
            results =  mapper.readValue(json, TypeFactory.defaultInstance().constructParametricType(Collection.class, clazz ) );
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
        return results;

An example of the JSON format it processes looks like:

"[{
  "@class" : "pack1.pack2.MyClass",
  "id" : null,
  "f1" : "",
  "f2" : 0.9933817827,
  ...
  "featureIndicator" : false
}]"

This excerpt of JSON includes only specific objects from a sample Java Set.

Answer №1

It seems like the issue lies in the default typing setting. The JSON structure you have generated does not align with what Jackson expects when default typing is enabled. To ensure compatibility, the beginning of your JSON should look like this:

["java.util.HashSet", [{

Additionally, make sure to include an extra closing bracket }]] at the end.

The discrepancy arises from using the toString() method on your set to generate the JSON. A better approach would be to utilize the ObjectMapper class configured with default typing, as shown below:

res = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(yourSet);

Answer №2

Perhaps this solution can assist someone in a similar situation. I encountered an error caused by using the toList() method of Stream.API, which returns an immutable collection resulting in a missing ArrayList type in the final JSON object after serialization. The issue was resolved by utilizing Collectors.toList()

Before

        List<B2bItem> itemIdList = branchDto.getOrders()
            .stream()
            .map(order -> order.getItems()
                    .stream()
                    .map(OrderItemDto::getB2bItem)
                    .toList())
            .flatMap(List::stream)
            .toList(); // <---

After

        List<B2bItem> itemIdList = branchDto.getOrders()
            .stream()
            .map(order -> order.getItems()
                    .stream()
                    .map(OrderItemDto::getB2bItem)
                    .toList())
            .flatMap(List::stream)
            .collect(Collectors.toList()); // <---

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Best location to structure data within a Ruby on Rails application

I am currently developing a Rails application that will generate a set of measurements collected over several days. Each measurement is saved as an individual record with a timestamp and a value, along with additional metadata. When I request the data (wi ...

What is the best way to determine the value of a variable specific to my scenario?

Using the Angular framework, I am trying to determine if the data variable updates when a button is clicked. Here is an example: <button ng-click='change()'>{{data}}</button> I want to verify if the data changes or log the data var ...

Strategies for aligning a div element in the middle of the screen

Positioned in the center of the current viewport, above all other elements. Compatible across different browsers without relying on third-party plugins, etc. Can be achieved using CSS or JavaScript UPDATE: I attempted to use Javascript's Sys.UI.Dom ...

Error retrieving content from website: Failed to connect to http://roblox.plus:2052/limiteds

Whenever I try to execute the code below, an error message pops up: file_get_contents(): failed to open stream: Connection refused $file = file_get_contents('http://roblox.plus:2052/limiteds'); $decode = json_decode($file, false); foreach ...

If the <option> "anyTableName" </option> is chosen, then display the column names of the selected table (PHP, MySQL)

Hey there, I'm a newbie on stackoverflow so feel free to correct me if I'm off base ;) Here's my current dilemma: I have a text.php file that contains 2 <select> elements. The first one allows me to choose a table (like "accounts", "c ...

I am having trouble accessing the input field in my AngularJS controller

Having an issue with my Ionic framework setup using AngularJS. I am unable to access the input field "groupName" in my controller, as it always returns "undefined". I was under the impression that using ng-model would automatically add it to the controlle ...

Issues encountered while attempting to verify password confirmation within a React form using Joi

I have been struggling to implement a schema for validating a 'confirm password' form field. While researching how to use Joi for validation, I noticed that many people recommend using the Joi.any() function. However, every time I attempt to use ...

What is the best way to assign Reference Identification numbers to the orders?

Is there a way for me to obtain and attach the id reference to the order? I have retrieved the product and user ids. When I utilize my get method, it should retrieve all the details about the products and users. For instance, the data will display compreh ...

What is the best way to input data into the verified full name box?

.html file executed code <input type="name" [(model)]="x.name" class="form-control" pattern="[a-z]" > Greetings to the members of Stack, I am in need of assistance. I am relatively new to Angular and I am looking for a way to validate the full nam ...

eliminate the common elements between two arrays in typescript/javascript

I have two lists of objects, each containing two fields: let users1 = [{ name: 'barney', uuid: 'uuid3'}, { name: 'barney', uuid: 'uuid1'}, { name: 'barney', uuid: 'uuid2 ...

Ways to include a variable in a string when using the .open("GET", "[...]") method

Is it possible to include a variable in the URL using JavaScript and PHP interaction? requeteAjax.open("GET", "../src/App/handler.php?id="); For instance, if the event number is 13, the desired URL should be: requeteAjax.open("GET", "../src/App/handler. ...

DOM not rendering Angular function output successfully

I recently delved into learning Angular and encountered a strange issue. Whenever I try to pull data using {{some.data.goes.here}} in the HTML, the result does not show up in the DOM. (function() { var app = angular.module('app', []); app. ...

Exploring the Depths of React Routing: The Power

I'm currently diving into React and trying to figure out how to create dynamic routes similar to partial pages in Angular. Here is my main App component: import React from 'react'; import Header from '../common/Header'; export d ...

Discover the hidden truth: Unveiling the enigma of React

I'm currently learning React and I've been working on some apps to enhance my skills and deepen my understanding. Right now, I am facing a challenge where I need to incorporate the logged user information into the Redux state. However, whenever I ...

Trigger an alert when a button is clicked and redirect the user to an newly opened tab

I recently created a button with a link that opens in a new tab. I also implemented some JavaScript to display an alert. Everything is working as expected, but after the user clicks "OK" on the alert, they remain on the same page. I would like to automati ...

Strings in Godot's gdscript containing escape characters retrieved from a database

I've been grappling with escape characters while developing a dialogue system in gdscript. My tool of choice is CastleDB, which has made it convenient to store nearly everything in data and empowering the writers to work on content outside the engine ...

Datatables.js columns mismatch issue

Currently, I am facing an issue while trying to implement a datatables functionality using datatables.js in my asp.net core NET 7.0 project. The error message that keeps popping up states that there is an incorrect number of columns in the table. I have se ...

javascript/AngularJS - make elements gradually disappear

I need help implementing a fade effect for an icon in the middle of a picture that indicates scrollability to the user. Currently, when the user scrolls, I can hide the icon but would like to add a nice smooth fade-out effect. Here is the HTML code snippe ...

Error Encountered with Nested Angular Material Tabs

Is there a way to prevent changes made to the upper tab in md-align-tabs attribute from affecting the inner tab when one tab is nested inside another using md-tabs? If so, how can I achieve this? <md-content layout="column" layout-fill> <md-ta ...

Using the Mousetrap binding on a nuxt.js page may not be effective

Hey there! I'm trying to achieve a certain functionality where I want to redirect to a different page once a specific sequence is typed. Although I can see the message "It works" in my console, the redirection is not happening and instead, I am gettin ...