Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson: deserializing recursive object

I'm trying to parse the filter parameters sent by a KendoUI grid to my web service and am having some issues convincing Jackson to parse this JSON. As far as I know, I can control the format of the parameters that Kendo sends, but I do not know how I would marshal the parameters into a better format so they remain unchangeable for now.

I intend to convert these parameters into a SQL query for an Oracle database.

Example JSON:

{
    "filters":
    [
        {
            "field": "Name",
            "operator": "contains",
            "value": "John"
        },
        {
            "filters": [
                {
                    "field": "Age",
                    "operator": "gt",
                    "value": 20
                },
                {
                    "field": "Age",
                    "operator": "lt",
                    "value": 85
                }
            ],
            "logic", "and"
        },
        {
            "field": "Address",
            "operator": "doesnotcontain",
            "value": "street"
        }
    ],
    "logic": "or"
}

Filters. Java

public class Filters {
    private List<Filter> filters;
    private String logic;
    // accessors/mutators/toString
}

Filter.java

public class Filter {
    private String field;
    private String operator;
    private String value;
    // accessors/mutators/toString
}

Unit Test

public class KendoGridFilterTest {
    private ObjectMapper mapper;

    @Before
    public void before() {
        mapper = new ObjectMapper();
    }

    @Test
    public void jsonParseTest() {
        final String json = "{\"filters\":[{\"field\":\"Name\",\"operator\":\"contains\",\"value\":\"John\"},{filters: [{\"field\":\"Age\",\"operator\": \"eq\",\"value\": 85},{\"field\": \"Age\",\"operator\": \"eq\",\"value\": 85}]\"logic\", \"and\",},{\"field\": \"Address\",\"operator\": \"doesnotcontain\",\"value\": \"street\"}],\"logic\":\"or\"}";
        Filters filters = mapper.readValue(json, Filters.class);
        assertTrue(json.equals(filters.writeValueAsString(filters);
    }
}

Errors

com.fasterxml.jackson.databind.UnrecognizedPropertyException: Unrecognized field 
    'logic'(com.example.Filter) not market as ignorable (3 known properties 
    "value", "field", "operator")
at [Source: java.io.StringReader@3bb2b8; line: 1, column 76] (through reference 
    chain: com.example.Filters["filters"]->com.example.Filter["logic"]

I've also tried adding @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") to the Filters class and get the same errors.

like image 916
johnktims Avatar asked Jul 12 '13 19:07

johnktims


People also ask

What is Jackson object serialization?

Jackson is a solid and mature JSON serialization/deserialization library for Java. The ObjectMapper API provides a straightforward way to parse and generate JSON response objects with a lot of flexibility.

What is the use of Jackson ObjectMapper?

ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.

How does Jackson read nested JSON?

A JsonNode is Jackson's tree model for JSON and it can read JSON into a JsonNode instance and write a JsonNode out to JSON. To read JSON into a JsonNode with Jackson by creating ObjectMapper instance and call the readValue() method. We can access a field, array or nested object using the get() method of JsonNode class.

What is @JsonManagedReference and @JsonBackReference?

The @JsonManagedReference annotation is a forward reference that includes during the serialization process whereas @JsonBackReference annotation is a backreference that omits during the serialization process. In the below example, we can implement @JsonManagedReference and @JsonBackReference annotations.


1 Answers

your Filter class is not correct. It should extend Filters. After correcting your unit test (json is incorrect) it can load your json into a Filters Object.

public class Filter extends Filters {
    private String field;
    private String operator;
    private String value;
    // accessors/mutators/toString
}
like image 86
Antoine Wils Avatar answered Oct 19 '22 03:10

Antoine Wils