【问题标题】:How to use dynamic property names for a Json object如何为 Json 对象使用动态属性名称
【发布时间】:2019-09-05 04:08:20
【问题描述】:

我们如何使 JSON 属性名称动态化。例如

public class Value {
    @JsonProperty(value = "value")
    private String val;

    public void setVal(String val) {
        this.val = val;
    }

    public String getVal() {
        return val;
    }
}

当序列化这个对象时,它被保存为{"value": "actual_value_saved"},但我想让密钥也像{"new_key": "actual_value_saved"} 一样动态。非常感谢任何帮助。

【问题讨论】:

  • 您想只用"new_key" 保存它,还是想有时用"new_key" 保存它,有时用"value" 保存它?如果是,基于什么理由?
  • @Bentaye 是的,基于名称可能会更改的要求。可以是"value""new_key""any_random_string"
  • @Prasad 您从哪里获得所需的字段名称?你能在你的 Value 对象中计算它吗?
  • @Bentaye 我已经通过使用自定义JsonSerializerJsonTypeInfo 的解决方案允许我们修改值但不能修改键。我的要求是有一个动态密钥。我想使用这个 POJO 作为一个公共对象来打印类似 {"name": "user"} {"phone": "1234567890"} 的东西。

标签: java json spring-boot jackson


【解决方案1】:

你可以使用JsonAnySetterJsonAnyGetter注解。后面可以使用Map 实例。如果您始终使用one-key-object,则可以使用Collections.singletonMap,在其他情况下使用HashMap 或其他实现。下面的示例显示了您可以轻松地使用这种方法并根据需要创建任意数量的随机key-s:

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        DynamicJsonsFactory factory = new DynamicJsonsFactory();
        ObjectMapper mapper = new ObjectMapper();

        System.out.println(mapper.writeValueAsString(factory.createUser("Vika")));
        System.out.println(mapper.writeValueAsString(factory.createPhone("123-456-78-9")));
        System.out.println(mapper.writeValueAsString(factory.any("val", "VAL!")));
    }
}

class Value {

    private Map<String, String> values;

    @JsonAnySetter
    public void put(String key, String value) {
        values = Collections.singletonMap(key, value);
    }

    @JsonAnyGetter
    public Map<String, String> getValues() {
        return values;
    }

    @Override
    public String toString() {
        return values.toString();
    }
}

class DynamicJsonsFactory {

    public Value createUser(String name) {
        return any("name", name);
    }

    public Value createPhone(String number) {
        return any("phone", number);
    }

    public Value any(String key, String value) {
        Value v = new Value();
        v.put(Objects.requireNonNull(key), Objects.requireNonNull(value));

        return v;
    }
}

上面的代码打印:

{"name":"Vika"}
{"phone":"123-456-78-9"}
{"val":"VAL!"}

【讨论】:

    【解决方案2】:

    您可以将所有可能的名称作为变量,并对它们进行注释,以便它们在为空时被忽略。这样,您只能在 JSON 中获取具有值的那个

    然后更改您的设置器以输入映射到您想要的键的变量。

    class Value {
    
        @JsonProperty("val")
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private String val;
    
        @JsonProperty("new_key")
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private String newKey;
    
        @JsonProperty("any_random_string")
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private String anyRandomString;
    
        public void setVal(String s) {
            if(/* condition1 */)
                this.val = s;
            else if (/* condition2 */) {
                this.newKey = s;
            } else  if (/* condition3 */) {
                this.anyRandomString = s;
            }
        }
    
    }
    

    【讨论】:

    • 虽然想法很聪明,但每次读取的字段数并不相同。它们往往会及时更改,因此在这种方法中,我可能需要在每次字段更改时更新代码。
    【解决方案3】:

    好问题@Prasad,这个答案与 JAVA 或 SPRING BOOT 无关,我只是提出这个答案,因为我搜索过使用 node 来做到这一点,并希望这能以某种方式帮助某人。在 JAVASCRIPT 中,我们可以为 JSON 对象添加动态属性名称,如下所示

    var dogs = {};
    
    var dogName = 'rocky';
    
    dogs[dogName] = {
        age: 2,
        otherSomething: 'something'
    };
    
    dogName = 'lexy';
    
    dogs[dogName] = {
        age: 3,
        otherSomething: 'something'
    };
    
    console.log(dogs);

    但是当我们需要动态改名字的时候就不得不

    1. 获取该属性
    2. 并创建另一个具有相同内容和新名称的属性
    3. 并从 JSON 中删除旧属性
    4. 将新属性分配给 JSON

    除此方法外,还有另一种动态更改 JSON 名称的方法,在此先感谢

    【讨论】:

      猜你喜欢
      • 2010-12-20
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多