[英]Parsing dynamic JSON values to Java objects
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):
让我向您展示一些示例(已转换为JSON,因为已通过REST请求发送到服务器):
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. 现在我需要在一个将构建SQL查询的
WHERE
子句的辅助类中解析该JSON。 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? 在PHP中这不是问题,因为我可以调用
json_decode
,然后简单地检查一些值是array
, string
还是其他任何东西......但是如何在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). 到目前为止,我使用的是Spring的
JsonJsonParser
(我没有发现像Jackson
, Gson
和其他人一样使用Spring的不同解析器之间有任何明显的区别)。
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... 我正在考虑使用三种不同的构造函数创建一个自己的数据对象类,或者为这三种可能性创建三个数据对象类,但是我不知道在解析器解析JSON之后如何处理为
column_name
返回的值 。 ..
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? 任何想法或线索?
Jackson's ObjectMapper treeToValue should be able to help you. Jackson的ObjectMapper treeToValue应该能够帮到你。
http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/ObjectMapper.html#treeToValue%28com.fasterxml.jackson.core.TreeNode,%20java.lang.Class%29 http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/ObjectMapper.html#treeToValue%28com.fasterxml.jackson.core.TreeNode,%20java.lang.Class %29
Your main problem is that the first version of you JSON is not the same construction than the two others. 您的主要问题是您的第一个版本JSON与其他两个版本的结构不同。 Picking the two others you could deserialize your JSON into a
Map<String, Map<String, String>
as you said but the first version fits a Map. 挑选其他两个你可以将你的JSON反序列化为
Map<String, Map<String, String>
如你所说,但第一个版本适合Map。
There are a couple solutions available to you : 有几种解决方案可供您使用:
Map<String, Map<String, String>
pattern Map<String, Map<String, String>
模式匹配 try
with one of the Map patterns, catch JsonProcessingException, then retry with the other Map pattern try
使用其中一个Map模式,捕获JsonProcessingException,然后使用其他Map模式重试 You'll have to check the type of the values in runtime. 您必须在运行时检查值的类型。 You can work with a
Map<String, Object>
or with JsonNode
. 您可以使用
Map<String, Object>
或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>\"}]}"
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.