What is the best way to deserialize a collection of enum values with Jackson JSON?

Currently, I am developing a configuration system where I aim to load config values from a JSON file and have them automatically converted into the required Java type. My choice for JSON parsing is Jackson, which works well with primitive types like floats and strings. However, I've encountered an issue when it comes to converting enums.

Let's consider the following enum:

public enum SystemMode
{
    @JsonProperty("Mode1")
    MODE1("Mode1"),
    @JsonProperty("Mode2")
    MODE2("Mode2"),
    @JsonProperty("Mode3")
    MODE3("Mode3");

    private final String name;

    private SystemMode(String name)
    {
        this.name = name;
    }

    @Override
    @JsonValue
    public String toString()
    {
        return this.name;
    }    
}

Suppose I want to represent a list of values of this enum in a JSON format as shown below:

{ 
    "Project" : "TEST",
    "System" : {
        "ValidModes" : ["Mode1", "Mode2"]
      }
}

And my desired approach would be something similar to the code snippet below:

ArrayList<SystemMode> validModes = (ArrayList<SystemMode>) configurator.getConfigValue("/System/ValidModes");

In my configurator class, the getConfigValue method simply acts as a thin layer over the Jackson JSON parsing process:

public Object getConfigValue(String JSON_String)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(JSON_String);
    return objectMapper.convertValue(node, Object.class);
}

When I execute the above code, Jackson correctly identifies that an ArrayList is needed but instead of returning an ArrayList of SystemMode enums, it provides an ArrayList of Strings, leading to an exception. Despite trying various data representations, Jackson persists in returning a list of strings rather than enums.

Hence, my query is:

How can I modify Jackson (version 2.9.4) to deserialize a list of enum values accurately in a way that aligns with my single "Object getConfigValue()" method?

Answer №1

Below is the correct method for binding your enum:

public List<SystemMode> fetchConfigValues(String path)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(path);
    return objectMapper.convertValue(node, new TypeReference<List<SystemMode>>(){});
}

Another approach is to manually convert the list of Strings like this:

List<SystemMode> result = jsonResult.stream().map(SystemMode::valueOf).collect(Collectors.toList());

A third option would be:

public <T>List<T> retrieveConfigValues(String path, Class<T> type)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(path);
    CollectionType toType = 
    objectMapper.getTypeFactory().constructCollectionType(List.class, type);
    return objectMapper.convertValue(node, toType);
}

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

What is the best method to extract a specific value from a JSON object?

I have parsed a JSON file to extract data such as "Floor", "flat_no", and "Flat_id". Here is an example of the JSON structure: { "results": [ { "Flat_id": "1", "cat": "2", "Flat_no": "101", "Floor": "1", "Flat_t ...

Java Selenium WebDriver encountered an exception: The error is unknown and is related to a missing 'value' in the function result

Help needed! I'm encountering an exception when attempting to run my first Selenium WebDriver test case in Java. Can anyone assist? Thanks! Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 48523 Only local connecti ...

Decode the JSON serialized format generated by CircularJSON

I have a JSON object in my node.js code that contains circular references. To send this information to the browser, I utilized the NPM package circular-json to stringify the object and serialize the circular references: var CircularJSON = require("circula ...

Preserve data across all pages using sessions

On my website, I have a pagination system where each page displays 10 data entries. Whenever a user clicks on the pagination buttons, it triggers a request to the database to fetch the corresponding records. Each data entry also includes a button that can ...

Is there a way to convert JSON to a Java object through mapping?

ObjectMapper mapper=new ObjectMapper(); String response1=client.execute(request1, responseHandler); Map jsonObject=mapper.readValue(response1, Map.class); List<Integer> idsList = new ArrayList<>(); JSONArray jsonArray = jsonObject.getJSON ...

Ways to extract useful information from a JSON response

Upon receiving a response from the server with details about various flowers and their quantities, I aim to display this information in a table. However, I am facing difficulty retrieving the values for the "Quantity" column. The code snippet below showcas ...

Decode a JSON entity featuring a distinct layout and identical identifier

I have developed an application that utilizes web scraping techniques to extract movie information from IMDb. The movie data is obtained by parsing the source code of the respective movie pages, some of which are formatted in JSON using the "Schema.org" mo ...

What is the best way to insert information into a complicated JSON dictionary using Python?

My task involves populating a JSON API Payload before sending it in the API request. The process includes working with 2 files: A text file containing JSON payload format, named json.txt A yml file containing actual data, named tdata.yml. I am developing ...

When trying to access data within objects using JSON iteration, it may lead to encountering an issue of reading a

Attempting to retrieve specific data from a JSON file obtained from a website has proven challenging. While iterating through the collection of objects, undefined values are constantly encountered. Unfortunately, if the JSON is poorly structured, modificat ...

Using jQuery UI autocomplete to insert the description of the selected item into a text field

Currently, I have a functional autocomplete text box with the following code: $('#material_number').autocomplete({ source: function(request, response) { $.ajax({ url: "index.cfm?action=leadtime.getmaterialleadtime& ...

Transfer information to firebase using a Java class and fetch a single attribute in a different activity

Firebase Database LinkI've been encountering an issue while trying to store data in Firebase using a particular code snippet. Previously, I was able to save data by creating new children under users>uid without any problems. However, now that I am att ...

Tips for manipulating JSON data in Azure Data Factory

Received the data in env_variable.json using a Lookup variable and looking to extract "NO" and "BR" programmatically for iteration within a ForEach activity. The content of the file is as follows: { "countries" : { "NO" : { "wells": ["0015/abcd"] }, "BR" ...

Obtain the key by using the JSON value

I am seeking to identify the recursive keys within a JSON Object. For instance, consider the following JSON Object: { "Division1" : { "checked": true, "level": 1, "District1-1": { "checked": true, "level ...

Using JSON Serialization in MVC3

How do I handle JSON serialization for the object being returned as null in my controller? public class CertRollupViewModel { public IEnumerable<CertRollup> CertRollups { get; set; } } public class CertRollup { public decimal TotalCpm { get ...

Choose the minimum price from the JSON response of the API

I have made an AJAX request to an API and received the following JSON response below. I am trying to extract the lowest 'MinPrice' from the 'Quotes' data but finding it challenging to determine the best approach. One method I am consid ...

Instructions for setting a default value for ng-options when dealing with nested JSON data in AngularJS

I need help setting a default value for my ng-options using ng-init and ng-model with dependent dropdowns. Here is an example of my code: <select id="country" ng-model="statessource" ng-disabled="!type2" ng-options="country for (country, states) in c ...

Generating and consuming XML data with swagger-node

As a newcomer to swagger-node (swagger-spec 2.0), I am looking to have my API consume and produce both XML and JSON as requested by the customer. Currently, I have only focused on the "producing" aspect of it. When it comes to producing a response, I am a ...

Customizing response headers in vanilla Node.js

My Node.js setup involves the following flow: Client --> Node.js --> External Rest API The reverse response flow is required. To meet this requirement, I am tasked with capturing response headers from the External Rest API and appending them to Nod ...

Extract the content from the division and set it as the image source

Looking for a way to retrieve the content from a div and insert that into the 'src' parameter of an image. Working on a project where JSON is used to load translation files, preventing me from loading images directly, but I want to at least load ...

Java programming language, Selenium WebDriver

Here is a snapshot of the Login popup: https://i.stack.imgur.com/iBal9.png I am new to Selenium webdriver and I have written some code to test navigation commands. However, when the browser opens, a login popup appears that I am unable to close using clas ...