当前位置: 首页 > 面试题库 >

基于Jackson中另一个字段值的条件字段要求?

江智
2023-03-14
问题内容

考虑具有一个字符串和两个数组的JSON表示形式。例如,

{
    "type" : "A",
    "ListA" : []
    "ListB" : [3, 4, 5]
 }

在上述情况下,type需要现场,但ListAListB有条件地
基于所述值所需的反序列化type。换句话说,ListA如果只需要type有值AListB如果只要求type有一个值B

当前,我在Jackson和Java中工作,并且能够type通过创建POJO以下代码来实现使字段成为强制性的:

public class Example {
    @JsonProperty(required = true)
    String type;

    // getter and setter auto-generated

但我不能只是附加其他@JsonProperty(required = true)ListAListB因为它依赖的价值type

我怎么能有条件地要求ListAListB反序列化基础上的价值type

另外,我将要执行额外的检查,例如,是否任一ListAListB为空数组(size == 0)或没有。


问题答案:

您可以使用自定义解串器来实现它。

定义模型

您的Example课程如下:

public class Example {

    private String type;
    private List<Integer> listA;
    private List<Integer> listB;

    // Getters and setters omitted    
}

创建自定义解串器

您的自定义解串器可能如下:

public class ExampleDeserializer extends StdDeserializer<Example> {

    private static final String TYPE_A = "A";
    private static final String TYPE_B = "B";

    public ExampleDeserializer() {
        super(Example.class);
    }

    @Override
    public Example deserialize(JsonParser p, DeserializationContext ctxt) 
                   throws IOException, JsonProcessingException {

        ObjectMapper mapper = (ObjectMapper) p.getCodec();  
        JsonNode tree = mapper.readTree(p);

        Example example = new Example();

        JsonNode typeNode = tree.get("type");
        if (typeNode == null || typeNode.asText().isEmpty()) {
            throw ctxt.mappingException("\"type\" is required");
        }
        example.setType(typeNode.asText());

        switch (typeNode.asText()) {

        case TYPE_A:
            ArrayNode listANode = (ArrayNode) tree.get("ListA");
            if (listANode == null || listANode.size() == 0) {
                throw ctxt.mappingException(
                           "\"ListA\" is required when \"type\" is \"" + TYPE_A + "\"");
            }
            example.setListA(createList(listANode));
            break;

        case TYPE_B:
            ArrayNode listBNode = (ArrayNode) tree.get("ListB");
            if (listBNode == null || listBNode.size() == 0) {
                throw ctxt.mappingException(
                           "\"ListB\" is required when \"type\" is \"" + TYPE_B + "\"");
            }
            example.setListB(createList(listBNode));
            break;

        default:
            throw ctxt.mappingException(
                       "\"type\" must be \"" + TYPE_A + "\" or \"" + TYPE_B + "\"");
        }


        return example;
    }

    private List<Integer> createList(ArrayNode arrayNode) {
        List<Integer> list = new ArrayList<Integer>();
        for (JsonNode node : arrayNode) {
            list.add(node.asInt());
        }
        return list;
    }
}

注册自定义反序列化器

将上面定义的自定义解串器注册到您的ObjectMapper

SimpleModule module = new SimpleModule("ExampleDeserializer", 
        new Version(1, 0, 0, null, "com.example", "example-deserializer"));

ExampleDeserializer exampleDeserializer = new ExampleDeserializer();
module.addDeserializer(Example.class, exampleDeserializer);

ObjectMapper mapper = new ObjectMapper()
                          .registerModule(module)
                          .enable(SerializationFeature.INDENT_OUTPUT);

测试您的自定义解串器

使用自定义序列化器:

String json = "{\"type\":\"A\",\"ListA\":[1,2,3]}";
Example example = mapper.readValue(json, Example.class);


 类似资料:
  • 问题内容: 这是基本的内容,但是我对VBA和Word / Access对象模型不熟悉。 我有一个大约117000条记录的两列数据库。列是“姓”和“计数”。我希望用户能够在文本框中键入SMITH并单击“提交”。然后,我想运行类似 并以字符串形式返回table.count的值。 感觉这应该是五到六行代码(我有,但不会发布),但是我显然缺少了一些东西! 干杯 问题答案: 首先,请小心命名“ count”

  • 假设我有两个字段F1和f2。我想将F1更新为。我可以在Mongo中使用一个更新命令吗?

  • 我开始使用验证框架用jax-rs验证json请求 是否可以根据另一个字段验证一个字段? 提前致谢

  • 问题内容: 我有一个MySQL表和模型包含的字段,以及。我也有另一个表/模型也包含,和。 假设已经充满了桌子,和。 当我以表格形式输入数据时,当我选择与表格相关的“ 通过”下拉字段时,我希望相关和字段能够自动填写。 我的for 看起来像这样: 根据建议,在控制器中添加了以下内容: 问题答案: 您所需要的只是调用请求以获取必填字段。就像下面这样: (我不知道您的型号名称)查看您的表格,看看您的字段是

  • 问题内容: 如何查询或过滤一个字段不等于另一个字段?即,其中document1.city1.name不等于document1.city2.name。 这个的一些版本? http://www.elasticsearch.org/guide/zh- CN/elasticsearch/reference/current/search-request-script- fields.html 问题答案: 是

  • 问题内容: 我有一个模型,希望包含一个主题名称及其首字母。(数据在某种程度上是匿名的,并且通过缩写来跟踪。) 现在,我写了 如最后一行所示,我希望能够将姓名的首字母实际作为字段(与名称无关)存储在数据库中,但是会使用基于名称字段的默认值进行初始化。但是,我遇到了问题,因为Django模型似乎没有“自我”。 如果将行更改为,则可以执行syncdb,但不能创建新主题。 在django中,有一个可调用函