问题描述
如何使用java动态过滤数据,假设我们有数据(没有pojo映射的map/json数组列表)
[
{
"id": "1001","type": "Internal","status": "Closed"
},{
"id": "1002","type": "External",{
"id": "1003","status": "Open"
},{
"id": "1004","status": "Open"
}
]
现在我们需要将过滤后的数据输出为 id > 1001 and ( type: 'External' or status: 'Open" )
[
{
"id": "1002","status": "Open"
}
]
对如何实现这一目标有任何建议吗?
解决方法
使用 JSON 路径,下面是我作为示例发布的几个 JSONPath
查询
P.S :- Ur "Id" 应该是 Integer 类型的操作 > 或 <
代码:-
public static void main(String[] args) {
String jsonData = "[\r\n" +
" {\r\n" +
" \"id\": 1001,\r\n" +
" \"type\": \"Internal\",\r\n" +
" \"status\": \"Closed\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"id\": 1002,\r\n" +
" \"type\": \"External\",\r\n" +
" {\r\n" +
" \"id\": 1003,\r\n" +
" \"status\": \"Open\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"id\": 1004,\r\n" +
" \"status\": \"Open\"\r\n" +
" }\r\n" +
"]";
String filterId = "$.[?(@.id > 1001)]"; //For Id > 1001
String filterType = "$.[?(@.type in ['External'])]"; //for External type
String filterTypeAndId = "$.[?((@.id > 1001) && (@.type in ['Internal']))]"; //for External type with Id > 1001
String filterTypeAndId2 = "$.[?((@.id > 1001) && (@.type in ['Internal','External']))]"; //for External type with Id > 1001
DocumentContext documentContext = JsonPath.parse(jsonData);
System.out.println(documentContext.read(filterId).toString());
System.out.println(documentContext.read(filterType).toString());
System.out.println(documentContext.read(filterTypeAndId).toString());
System.out.println(documentContext.read(filterTypeAndId2).toString());
}
结果是:-
[{"id":1002,"type":"External","status":"Closed"},{"id":1003,"type":"Internal","status":"Open"},{"id":1004,"status":"Open"}]
[{"id":1002,"status":"Closed"}]
[{"id":1003,"status":"Open"}]
,
我们可以使用 javascript 功能来解决条件。我们可以使用 Java ScriptEngineManager 来运行 javascript 表达式:
表达式可以是 type = 'Internal' AND status ='Open'
private String getResult(String expression) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
try {
return engine.eval(expression).toString();
} catch (Exception e) {
}
return null;
}
您可以通过以下方法实现此目的:-
- 将json转成字符串
- 构造 JSONArray >> JSONArray jsonArray = new JSONArray(converted_json_String)
- 从 JsonArray 中取出 jsonArrayObject 并构造一个列表
- 使用 Collections.sort 方法并将您的比较逻辑部署到 JSON 键上 并构建您的排序 json。
试试这个代码,我假设你有一个对象列表。
List<YourCLass> filteredList = list
.stream()
.filter(obj -> obj.getId() > 1001 && (obj.getStatus().equals("Open") || obj.getType().equals("External")))
.collect(Collectors.toList());
filteredList 包含您期望的对象列表,使用 Object mapper 可以将其获取为 json 格式。
String filteredObjJson = new ObjectMapper().writeValuesAsString(filteredList);
在 pom.xml 中添加此依赖项或下载 lib 并将其添加到您的库中
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>