java 如何使用注释在jackson的反序列化过程中强制执行A​​CCEPT_SINGLE_VALUE_AS_ARRAY

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39041496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:02:12  来源:igfitidea点击:

How to enforce ACCEPT_SINGLE_VALUE_AS_ARRAY in Hymanson's deserialization process using annotation

javajsonspringHymanson

提问by Vahid

Is there a way to use annotation on a List property in a class to use ACCEPT_SINGLE_VALUE_AS_ARRAYin Hymanson? I'm using Spring and getting the below exception

有没有一种方法来使用注释在类中的列表属性使用ACCEPT_SINGLE_VALUE_AS_ARRAYHymanson?我正在使用 Spring 并收到以下异常

nested exception is com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token

嵌套异常是 com.fasterxml.Hymanson.databind.JsonMappingException:无法从 VALUE_STRING 令牌中反序列化 java.util.ArrayList 的实例

Assume I have a class as below:

假设我有一个类如下:

public class MyClass {

    private List < String > value;
}

And my JSON structures are as below:

我的 JSON 结构如下:

case 1:

情况1:

[{"operator": "in", "value": ["Active"], "property": "status"}]

case 2:

案例2:

[{"operator": "like", "value": "aba", "property": "desc"}]

What annotation should I use to let the framework know I want these 2 cases to be treated the same when deserializing.

我应该使用什么注释来让框架知道我希望在反序列化时对这两种情况进行相同的处理。

UPDATE:I moved the updates to an answer in this post for more clarity.

更新:为了更清楚,我将更新移到了这篇文章中的一个答案。

采纳答案by Vahid

I'm just answering my own question for clarity. One of the answers was to upgrade to the higher version so that I can use annotations. I cannot do it due to dependency restrictions of my project.

为了清楚起见,我只是在回答我自己的问题。答案之一是升级到更高版本,以便我可以使用注释。由于我的项目的依赖性限制,我无法这样做。

As a result, based on Michal Foksa answer I solved my problem by creating a custom deserializer. Its as below:

因此,根据 Michal Foksa 的回答,我通过创建自定义解串器解决了我的问题。它如下:

On my property:

在我的财产上:

@JsonDeserialize(using = CustomStringDeserializer.class)
private List<String> value;

And my Deserializer:

还有我的解串器:

public class CustomStringDeserializer extends JsonDeserializer<List<String>>{

    @Override
    public List<String> deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(DeserializationFeature. ACCEPT_SINGLE_VALUE_AS_ARRAY);
        return mapper.readValue(p, List.class);
    }

}

回答by ?mer Erden

You can use @JsonFormatannotation,

您可以使用@JsonFormat注释,

public class MyClass {

    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private List<String> value;

}

To work with this you need to have Hymanson version min 2.7.0. You can also use other available JsonFormat Features

要使用此功能,您需要拥有 Hymanson 版本min 2.7.0。您还可以使用其他可用的JsonFormat 功能

For version 2.6.x

对于 2.6.x 版

@Autowired private ObjectMapper mapper;
//...

mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
  • Add this code to your Initializer Class.
  • Or you can directly configure Hymansonin your Bean Configuration
  • 将此代码添加到您的Initializer Class.
  • 或者你可以直接Hymanson在你的Bean Configuration

These would solve the issue but it will be activated for every deserializationprocess.

这些将解决问题,但它将为每个deserialization进程激活。

回答by Michal Foksa

I would create a custom JsonDeserializerwhere I would deal with both cases and annotate value class property with the deserializer.

我将创建一个自定义JsonDeserializer,我将在其中处理这两种情况并使用反序列化器注释值类属性。

Deserializer:

解串器:

public class StringListDeserializer extends JsonDeserializer<List<String>>{

    @Override
    public List<String> deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        List<String> ret = new ArrayList<>();

        ObjectCodec codec = parser.getCodec();
        TreeNode node = codec.readTree(parser);

        if (node.isArray()){
            for (JsonNode n : (ArrayNode)node){
                ret.add(n.asText());
            }
        } else if (node.isValueNode()){
            ret.add( ((JsonNode)node).asText() );
        }
        return ret;
    }
}

MyClass:

我的课:

public class MyClass {
    .
    @JsonDeserialize(using = StringListDeserializer.class)
    private List<String> value;
    .
}

Hope it helps.

希望能帮助到你。

BTW: If there is a way how to deal with such a case with just an annotation, I also want to know it.

BTW:如果有什么办法可以只用一个注解来处理这种情况,我也想知道。

回答by javaPlease42

If this project is a Spring project then you can put this property in you application.properties:

如果这个项目是一个 Spring 项目,那么你可以把这个属性放在你身上application.properties

spring.Hymanson.deserialization.UNWRAP_SINGLE_VALUE_ARRAYS=true

spring.Hymanson.deserialization.UNWRAP_SINGLE_VALUE_ARRAYS=true