In my application I have lot of overviews (tables) with sorting and filtering capabilities. And becuase the different column can hold different value type (strings, numbers, dates, sets, etc.) the filter for these columns also can bring different values. Let me show you few examples (converted to JSON already as is sent to server via REST request):
For simple string value it is like:
{"<column_name>":"<value>"}
For number and date column the filter looks like:
{"<column_name>":[{"operator":"eq","value":"<value>"}]}
{"<column_name>":[{"operator":"eq","value":"<value1>"},{"operator":"gt","value":"<value2>"}]}
For set the filter looks like
{"<column_name>":["<value1>","<value2>"(,...)]}
Now I need to parse that JSON within a helper class that will build the WHERE
clause of SQL query. In PHP this is not a problem as I can call json_decode
and then simply check whether some value is array
, string
or whatever else... But how to do this simply in Java?
So far I am using Spring's JsonJsonParser
(I didn't find any visible difference between different parsers coming with Spring like Jackson
, Gson
and others).
I was thinking about creating an own data object class with three different constructors or having three data object classes for all of the three possibilities, but yet I have no clue how to deal with the value returned for column_name
after the JSON is parsed by parser...
Simply looking on the examples it gives me three possibilities:
Map<String, String>
Map<String, Map<String, String>>
Map<String, String[]>
Any idea or clue?
You'll have to check the type of the values in runtime. You can work with a Map<String, Object>
or with JsonNode
.
JsonParser parser = JsonParserFactory.getJsonParser();
Map<String, Object> map = parser.parseMap(str);
Object filterValue = filter.get("<column_name>");
if (filterValue instanceof String) {
// str is like "{\"<column_name>\":\"<value>\"}"
} else if (filterValue instanceof Collection) {
for (Object arrayValue : (Collection<Object>) filterValue) {
if (arrayValue instanceof String) {
// str is like "{\"<column_name>\":[\"<value1>\",\"<value2>\"]}"
} else if (arrayValue instanceof Map) {
// str is like "{\"<column_name>\":[{\"operator\":\"eq\",\"value\":\"<value>\"}]}"
}
}
}
ObjectMapper mapper = new ObjectMapper();
JsonNode filter = mapper.readTree(str);
JsonNode filterValue = filter.get("<column_name>");
if (filterValue.isTextual()) {
// str is like "{\"<column_name>\":\"<value>\"}"
} else if (filterValue.isArray()) {
for (JsonNode arrayValue : filterValue.elements()) {
if (arrayValue.isTextual()) {
// str is like "{\"<column_name>\":[\"<value1>\",\"<value2>\"]}"
} else if (arrayValue.isObject()) {
// str is like "{\"<column_name>\":[{\"operator\":\"eq\",\"value\":\"<value>\"}]}"
}
}
}