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

后端 未结 4 2075
隐瞒了意图╮
隐瞒了意图╮ 2020-12-01 14:27

Is there a way to use annotation on a List property in a class to use ACCEPT_SINGLE_VALUE_AS_ARRAY in Jackson? I\'m using Spring and getting the b

相关标签:
4条回答
  • 2020-12-01 14:48

    You can use @JsonFormat annotation,

    public class MyClass {
    
        @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
        private List<String> value;
    
    }
    

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

    For version 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 Jackson in your Bean Configuration

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

    0 讨论(0)
  • 2020-12-01 14:48

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

    spring.jackson.deserialization.UNWRAP_SINGLE_VALUE_ARRAYS=true

    0 讨论(0)
  • 2020-12-01 14:49

    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:

    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);
        }
    
    }
    
    0 讨论(0)
  • 2020-12-01 14:50

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

    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.

    0 讨论(0)
提交回复
热议问题