Serialize and Deserialize PageImpl in Jackson

  1. Define an interface.
public interface IJPADataPage {
String _CLASS = "@class";
String CONTENT = "content";
String DIRECTION = "direction";
String IGNORE_CASE = "ignoreCase";
String NULL_HANDLING = "nullHandling";
String NUMBER = "number";
String PROPERTY = "property";
String SIZE = "size";
String SORT = "sort";
String TOTAL_ELEMENTS = "totalElements";
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;

import java.io.IOException;

@SuppressWarnings("unchecked")
public class JPADataPageSerializer
extends StdSerializer<PageImpl>
implements IJPADataPage {
public JPADataPageSerializer(Class<PageImpl> t) {
super(t);
}

public JPADataPageSerializer() {
this(null);
}

@Override
public void serialize(
PageImpl value,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(_CLASS, PageImpl.class.getName());
jsonGenerator.writePOJOField(CONTENT, value.getContent());
jsonGenerator.writeNumberField(NUMBER, value.getNumber());
jsonGenerator.writeNumberField(SIZE, value.getSize());
jsonGenerator.writeNumberField(TOTAL_ELEMENTS, value.getTotalElements());
jsonGenerator.writeArrayFieldStart(SORT);
if (!value.getSort().isEmpty()) {
for (Sort.Order order : value.getSort()) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(PROPERTY, order.getProperty());
jsonGenerator.writeStringField(DIRECTION, order.getDirection().name());
jsonGenerator.writeBooleanField(IGNORE_CASE, order.isIgnoreCase());
jsonGenerator.writeStringField(NULL_HANDLING, order.getNullHandling().name());
jsonGenerator.writeEndObject();
}
}
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
}

@Override
public void serializeWithType(
PageImpl value,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider,
TypeSerializer typeSer) throws IOException {
serialize(value, jsonGenerator, serializerProvider);
}
}
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unchecked")
public class JPADataPageDeserializer
extends StdDeserializer<PageImpl>
implements IJPADataPage {
public JPADataPageDeserializer(Class<?> type) {
super(type);
}

public JPADataPageDeserializer() {
this(null);
}

@Override
public PageImpl deserialize(
JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException {
JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
List<?> content = deserializationContext.readTreeAsValue(jsonNode.get(CONTENT), List.class);
int number = jsonNode.get(NUMBER).asInt(0);
int size = jsonNode.get(SIZE).asInt(1);
int totalElements = jsonNode.get(TOTAL_ELEMENTS).asInt(0);
List<Sort.Order> orders = new ArrayList<>();
ArrayNode arrayNode = (ArrayNode) jsonNode.get(SORT);
if (!arrayNode.isEmpty()) {
for (JsonNode jsonNodeOrder : arrayNode) {
String property = jsonNodeOrder.get(PROPERTY).asText();
Sort.Direction direction = Sort.Direction.valueOf(jsonNodeOrder.get(DIRECTION).asText());
boolean ignoreCase = jsonNodeOrder.get(IGNORE_CASE).asBoolean();
Sort.NullHandling nullHandling = Sort.NullHandling.valueOf(jsonNodeOrder.get(NULL_HANDLING).asText());
Sort.Order order = new Sort.Order(direction, property, nullHandling);
if (ignoreCase) {
order = order.ignoreCase();
}
orders.add(order);
}
}
PageRequest pageRequest = PageRequest.of(number, size, Sort.by(orders));
return new PageImpl(content, pageRequest, totalElements);
}

@Override
public Object deserializeWithType(
JsonParser jsonParser,
DeserializationContext deserializationContext,
TypeDeserializer typeDeserializer) throws IOException {
return deserialize(jsonParser, deserializationContext);
}
}
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.data.domain.PageImpl;

public class JPADataModule extends SimpleModule {
public static final String NAME = "JPA Data Module";
public static final Version VERSION = new Version(0, 1, 0, null, null, null);

public JPADataModule() {
super(NAME, VERSION);
addSerializer(PageImpl.class, new JPADataPageSerializer());
addDeserializer(PageImpl.class, new JPADataPageDeserializer());
}
}
objectMapper.registerModule(new JPADataModule());

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store