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
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
@Autowired private ObjectMapper mapper;
//...
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Initializer Class
.Jackson
in your Bean Configuration
These would solve the issue but it will be activated for every deserialization
process.
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
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);
}
}
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.