首页 > 解决方案 > 如何使用 Jackson 基于 JSON 值查找 getter 方法

问题描述

我有类似这样的json:

Groups":[
         {
            "LogicalOperator":"AND",
            "condition":[
               {
                  "column":"name",
                  "Operator":"CONTAINS",
                  "Value":"Shiva"
               },
               {
                  "column":"address",
                  "Operator":"NOT CONTAINS",
                  "Value":"Vijay Nagar"
               },
               {
                  "column":"city",
                  "Operator":"EQUAL",
                  "Value":"Bengaluru"
               },
               {
                  "column":"country",
                  "Operator":"NOT EQUAL",
                  "Value":"India"
               }
            ]
         }

如何根据值查找 getter 方法。示例:下面的列有“名称”、“地址”、“城市”和“国家”。

如果值是“名称”,那么我想动态地找到 getName() 方法,如果值是“地址”,那么它应该是 getAddress()...

下面是pojo:

public class CustomerPojo {

    private String name;
    private int age;
    private String address;
    private String city;
    private String country;

    
    public CustomerPojo(String name, String address, String city, String country,int age) {
        super();
        this.name = name;
        this.age=age;
        this.address = address;
        this.city = city;
        this.country = country;
    }
    
    

    @Override
    public int hashCode() {
        return Objects.hash(address, age, city, country, name);
    }



    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CustomerPojo other = (CustomerPojo) obj;
        return Objects.equals(address, other.address) && age == other.age && Objects.equals(city, other.city)
                && Objects.equals(country, other.country) && Objects.equals(name, other.name);
    }



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "CustomerPojo [name=" + name + ", age=" + age + ", address=" + address + ", city=" + city + ", country="
                + country + "]";
    }

}


以下是我尝试过的代码。但我想动态地做到这一点。

private List<CustomerPojo> groupOperatorAND(JsonNode condNode, List<CustomerPojo> list) {
        // String jsonNode = condNode
        // System.out.println(jsonNode);
        String column = condNode.findValue("column").asText();
        String operator = condNode.findValue("Operator").asText();
        String value = condNode.findValue("Value").asText();

        switch (operator) {

        case "CONTAINS":
            if (column.equals("name")) {
                containsList = list.stream().filter(li -> li.getName().contains(value)).collect(Collectors.toList());
            } else {
                containsList = list.stream().filter(li -> li.getAddress().contains(value)).collect(Collectors.toList());
            }
            // System.out.println(containsList);
            // objList.add(containsList);

            break;

        case "NOT CONTAINS":
            if (column.equals("name")) {
                notContainsList = containsList.stream().filter(li -> !li.getName().contains(value))
                        .collect(Collectors.toList());
            } else {
                notContainsList = containsList.stream().filter(li -> !li.getAddress().contains(value))
                        .collect(Collectors.toList());
            }
            // System.out.println(notContainsList);
            // objList.add(notContainsList);

            break;

        case "EQUAL":
            if (column.equals("name")) {
                equalList = notContainsList.stream().filter(li -> li.getName().equals(value))
                        .collect(Collectors.toList());
            } else {
                equalList = notContainsList.stream().filter(li -> li.getAddress().equals(value))
                        .collect(Collectors.toList());

            }
            // System.out.println(equalList);
            // objList.add(equalList);
            break;

        case "NOT EQUAL":
            if (column.equals("name")) {
                notEqualList = equalList.stream().filter(li -> !li.getName().equals(value))
                        .collect(Collectors.toList());
            } else {
                notEqualList = equalList.stream().filter(li -> !li.getAddress().equals(value))
                        .collect(Collectors.toList());
            }
            //System.out.println("AND Group Result --> " + notEqualList);
            // objList.add(notEqualList);
            break;

        default:
            System.out.println("No Operator matches");
        }
        return notEqualList;

    }

标签: javaspringjacksonjackson-databind

解决方案


如果将此代码放入静态方法或构造函数中,使其仅执行一次,它将构建一个映射,其中键是“列”名称,值是 CustomerPojo 类中关联的 get 方法。

final Map<String, Method> getters = Arrays.asList(CustomerPojo.class.getMethods()).stream()
        .filter(mth -> mth.getName().startsWith("get")).filter(mth -> !mth.getName().equals("getClass"))
        .collect(Collectors.toMap(
                        mth -> mth.getName().substring(3, 4).toLowerCase() + mth.getName().substring(4), mth -> mth));

代码流式传输来自 CustomerPojo 类的方法数组,并过滤​​掉除“getter”方法之外的所有方法。

然后它将剩余的方法收集到一个映射中,其中键是在剥离“get”并将第一个字符小写之后的 getter 的名称。

有了这个,你应该能够:

Method mth = getters.get(columnName);

推荐阅读