encountering issues while Deserializing a collection containing children objects of various types

I am facing an issue with deserializing a JSON packet that consists of a header (under PACKET_HEADER) and several different types of messages (under DATA). These messages have a parent class in common:

//parent message class
public class Message {

    public enum MessageType {
        WHOAREYOU,
        TimeData,
        Ready,
        LocationData
    }

    public MessageType getMessageType() {
        return MESSAGE_TYPE;
    }

    public void setMessageType(MessageType MessageType) {
        this.MESSAGE_TYPE = MessageType;
    }

    private MessageType MESSAGE_TYPE;
    //declaring public for simplicity
    public String SENDER;
    public String SENDER_TYPE;

}

//sample child class:
public class TimeMessage extends Message {

    private int tick;
    public int getTick()
    {
        return tick;
    }

And I am using the following code to deserialize the input:

 @Override
    public Handler create(Connector connector, Object packet, int clientID) {
        Gson gson = new Gson();
        Packet pack = gson.fromJson(packet.toString(), Packet.class);
        System.out.println("Number of messages : " + pack.PACKET_HEADER.NOF_MESSAGES );//ok
        for(Message msg : pack.DATA)
        {
            switch (msg.getMessageType()) {
                //enters the switch successfully
                case TimeData: {               
                    System.out.println("Sender:  " + msg.SENDER  + "  Sender_type: " + msg.SENDER_TYPE);//ok
                    TimeMessage time_msg = (TimeMessage) msg;//NOT ok, generates exception!!!!
                    //...
                    return new TimeHandler(time_msg, connector, clientID);
                }
                default:                    
                    System.out.println("Switch " + msg.getMessageType() + " is invalid");
                    return null;
            }
        }
       return null; 

    }

Can anyone provide any insights into why I am unable to cast to a child class? And how can I resolve this issue? Thank you in advance.

Answer â„–1

One thing to keep in mind is that Gson has limitations when it comes to handling polymorphism.

The main reason for this limitation is the fact that JSON doesn't include type information, which means that Gson can only deserialize objects into their base classes like Message but not into their subclasses like TimeMessage.

To overcome this issue, you need to use an additional component called the RuntimeTypeAdapterFactory.

If you want more information on how to implement this solution, I wrote an article about it on my blog:

You should check out the section labeled "Preserving Type Information" in the following link:

If you have any further questions or issues, feel free to ask.

Edit:

Here's a fully functional example tailored to your specific situation:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.typeadapters.RuntimeTypeAdapterFactory;

public class Program
{
    public static class Packet
    {
        public Message[] DATA;
    }

    public static enum MessageType
    {
        WHOAREYOU,
        TimeData,
        Ready,
        LocationData
    }

    public static class Message {

        public MessageType getMessageType() {
            return MESSAGE_TYPE;
        }

        public void setMessageType(MessageType MessageType) {
            this.MESSAGE_TYPE = MessageType;
        }

        private MessageType MESSAGE_TYPE;
        
        public String SENDER;
        public String SENDER_TYPE;

    }

    public static class TimeMessage extends Message
    {
        private int tick;
        public int getTick()
        {
            return tick;
        }
        public TimeMessage(int tick)
        {
            this.tick = tick;
        }
    }

    public static void main(String[] args)
    {
        Message[] messages = { new TimeMessage(123) };

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(Message.class, "$type").registerSubtype(TimeMessage.class));
        Gson gson = builder.create();

        String json = gson.toJson(messages);

        Message[] outMessages = gson.fromJson(json, Message[].class);
        TimeMessage tm = (TimeMessage)outMessages[0];
    }
}

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

Failed to save information in JSON format

I'm currently facing an issue with JSON while trying to implement a register and login feature. The data fails to be stored as intended. Here is the JSON response I am receiving in the log: 02-24 08:24:47.878: E/JSON(2017): {"tag":"register","success ...

Breaking down a large JSON array into smaller chunks and spreading them across multiple files using PHP pagination to manage the

Dealing with a large file containing over 45,000 arrays can be challenging, especially on a live server with high traffic. To address this issue, I used the array_chunk($array, 1000) function to divide the arrays into 46 files. Now, my goal is to access a ...

Unveiling the secrets of discovering the JsonPath associated with a specific key

If I have a sample JSON like the one below and want to extract the jsonPath for a key such as "city": { "fname" : "A", "lname" : "B", "city" : "LA" } I am considering: Using a Browser Extension Utilizing a Java Library Exploring Sublime/Atom Ext ...

Using Java's get() and getAttribute(), replace Selenium in C# for enhanced automation

Embarking on automation tasks in Selenium using Java, but now venturing into C# with selenium. Seeking guidance on how to translate the following Java logic into C# Visual Studio: Int count = driver.findelements(By.Name("radiobutton")).size(); For(int ...

"Discrepancy in results between JSON stringify and JavaScript object conversion

I need to save this object in a database, but first I have to send it to the backend. Recorder {config: Object, recording: false, callbacks: Object, context: AudioContext, node: ScriptProcessorNode…} However, after using JSON.stringify(recorder) The r ...

Guide to specifying optional JSON fields in Golang structures?

In my programming practice, I have a preference for using pointers with primitive data types in my structs. By doing so, I ensure that when I use json.Marshal to convert them, any nil fields are represented as "field": null in the resulting JSON string. Ho ...

Submit image and transfer it to server using AngularJS and Jersey

I need help with my form that contains the following fields: <div class="form-group"> <label>Username</label> <input type="text" ng-model="username" class="form-control"> </div> <div class="from-group"> < ...

Unable to remove MySQL row using AJAX and JSON

After successfully inserting rows into my MySQL database, I encountered an issue when trying to DELETE a row using the same logic. Despite following similar steps, I am unable to delete the specified row by its ID. I need assistance in identifying what is ...

Experiencing a result of NaN following a mathematical operation on variables

While working with an array obtained from a JSON response, I am encountering NaN after performing addition operations. var a = new Array(); var b = 0; var c = 0; alert(b); for (var x = 0; x < length; x++) { a[x] = response.data[x] } for (var i = 0; ...

Creating a JSON builder using arrayJson in Groovy is an effective way to easily

I'm a beginner in Groovy and I'm trying to create a JSON object using the builder { "query": { "bool": { "must": [ { "bool": { "should": [ ...

Encountered an issue with JSON parsing: Expected an array but received a string at line 1, column 1 while transferring data from PHP

I am facing an issue with my code. I need to extract values from a PHP script that encodes a JSON array; My PHP code : <?php $roro = array(); $roro[] = array( 'id' => '1', 'title' => 'title1' ...

Angular's GET request response is returning an "Undefined" value instead of the

As an Angular beginner, I've successfully set up and tested a service that retrieves data from a JSON file using the Get method. However, when attempting to access the data inside the JSON file, it returns as undefined. My goal is to use this data as ...

Executing multiple jar files in Python using multithreading results in longer execution times

I am currently utilizing ThreadPoolExecutor and assigning identical tasks to workers. The task involves running a jar file and performing certain operations on it, but I have encountered an issue related to timing. Scenario 1: When I submit a single task ...

Retrieving various values with identical paths from JSON files using the JSON map feature in SAS

Could anyone assist me in extracting multiple values from a JSON with the same path using a JSON map? Any assistance would be greatly appreciated. Thank you. JSON { "totalCount": 2, "facets": {}, "content": [ [ { "name": "custo ...

"Embarking on a journey with Jackson and the power

There have been numerous questions regarding the use of Jackson for serializing/deserializing Java objects using the builder pattern. Despite this, I am unable to understand why the following code is not functioning correctly. The Jackson version being use ...

Check for length validation including spaces in JavaScript

My code includes a functionality that calculates the length of characters in a text area using both JSP and JavaScript: <textarea class="textAreaLarge" id="citation" rows="20" cols="180" name="citation" ...

Retrieving the image field value using FSS in Plone 3.x

I am currently in the process of transferring an older Plone 3.3 website that utilizes FileSystemStorage with the help of Mikko's Simple JSON export script. Everything seems to be working smoothly, with the exception of missing values in the image fi ...

Passing parameters as an array in Angular can be done by using the format: ?category[]=1&category[]=2&category[]=3,

Struggling to send an array using the $http.get() method in AngularJS. Here's my current approach: $http.get('/events.json', {params: {category_id: [1,2]}}); While I anticipate the request to be sent as /events.json?category_id[]=1&cat ...

Using PHP to beautify JSON data

I'm currently working on generating JSON output for a specific JavaScript application, but I'm encountering a formatting issue that the script is not recognizing. Here's how I've structured my JSON so far: // setting up the feed $feed ...

Could not find an iframe element using the specified xpath

Every time I attempt to run the code below, I encounter an InvalidSelector exception: List<WebElement> allFrames = driver.findElements(By.xpath("//iframe")); org.openqa.selenium.InvalidSelectorException: Unable to find any element using the xpat ...