Skip to content

Instantly share code, notes, and snippets.

@darylteo
Last active November 8, 2022 10:48
Show Gist options
  • Save darylteo/a7be65b539c0d8d3ca0de94d96763f33 to your computer and use it in GitHub Desktop.
Save darylteo/a7be65b539c0d8d3ca0de94d96763f33 to your computer and use it in GitHub Desktop.
Jackson Deserializer based on several StackOverflow posts.
import java.util.List;
@Data
public class ArrayOrObject<T> {
private List<T> data;
private Boolean isObject;
}
/*
* http://stackoverflow.com/questions/20230114/jersey-jackson-and-jax-rs-post-multiple-json-formats
* http://stackoverflow.com/questions/36159677/how-to-create-a-custom-deserializer-in-jackson-for-a-generic-type
* http://stackoverflow.com/questions/31300046/how-to-use-jacksons-contextualdeserializer-for-root-values
*/
public static class ArrayOrObjectDeserializer
extends JsonDeserializer<ArrayOrObject>
implements ContextualDeserializer {
private Class<?> contentType;
@Override
public JsonDeserializer<?> createContextual(
DeserializationContext ctxt,
BeanProperty property
) throws JsonMappingException {
final JavaType wrapperType;
if (property == null) {
wrapperType = ctxt.getContextualType();
} else {
wrapperType = property.getType();
}
final JavaType contentType = wrapperType.containedType(0);
final ArrayOrObjectDeserializer deserializer = new ArrayOrObjectDeserializer();
deserializer.contentType = contentType.getRawClass();
return deserializer;
}
@Override
public ArrayOrObject deserialize(
final JsonParser jp,
final DeserializationContext ctxt
) throws IOException, JsonProcessingException {
final ArrayOrObject wrapper = new ArrayOrObject();
// Retrieve the object mapper and read the tree.
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode root = mapper.readTree(jp);
if (root.isArray()) {
final List list = new LinkedList();
// Deserialize each node of the array using the type expected.
final Iterator<JsonNode> rootIterator = root.iterator();
while (rootIterator.hasNext()) {
list.add(mapper.treeToValue(rootIterator.next(), this.contentType));
}
wrapper.setData(list);
wrapper.setIsObject(false);
} else {
wrapper.setData(Arrays.asList(mapper.treeToValue(root, this.contentType)));
wrapper.setIsObject(true);
}
return wrapper;
}
}
@darylteo
Copy link
Author

darylteo commented Sep 7, 2016

This will allow you to accept POST bodies that are either Arrays or single Objects. The isObject flag is there to determine what kind of response you wish to return if necessary.

@harry-airwallex
Copy link

Good job man!

@yyLuo0423
Copy link

Thanks for being so helpful!

@shadowrobot
Copy link

고마워요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment