6

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.

kuporific
  • 10,053
  • 3
  • 42
  • 46
johnktims
  • 581
  • 2
  • 7
  • 14
  • It looks like maybe the `Filters` class should also contain a `Filters` as a member too since the outside "filters" looks like there's another "filter" object inside of it (though it's weird that the outside one has quotes and the inside one does not). – kuporific Jul 12 '13 at 19:59
  • I fixed the omission of quotes. The issue that I see is that the parent and the child both have the same name, so I can't return the key "filters" unless the variable is named "filters" (or remapped using @JsonProperty(value="filters"). I think I'm getting a little confused by the recursive nature of this JSON. – johnktims Jul 12 '13 at 20:22
  • You have a getter and a setter for each private field? – robert_difalco Jul 12 '13 at 21:03
  • Yes, and I feel like there should be a Filter filters inside of the Filters class but I can't wrap my head around the conflicting "filters" that Jackson wants/needs to return. – johnktims Jul 12 '13 at 21:15
  • I changed "List filters" to "List filters" and my unit test passes. I printed the class name of the elements in filters.getFields() and they all say java.util.LinkedHashMap. – johnktims Jul 12 '13 at 22:02
  • Looks like http://stackoverflow.com/questions/15430715/casting-linkedhashmap-to-complex-object solves the problem. – johnktims Jul 12 '13 at 22:23

1 Answers1

2

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
}
Antoine Wils
  • 349
  • 2
  • 4
  • 21
  • Thanks! I merged Filter and Filters into one class and then added @JsonInclude(Include.NON_NULL) to the class to remove all of the fields that don't apply. – johnktims Jan 26 '14 at 03:20
  • I've tried several times to add my final solution but I keep getting an error saying "Your post appears to contain code that is not properly formatted as code." even though it's formatted correctly in the preview. – johnktims Jan 26 '14 at 03:59