版本
springboot:3.2.2
问题
使用Page/Sort类型作为controller参数时无法被正确解析
添加jackson模块支持反序列化
注:如果项目使用了spring-cloud-openfeign-core模块则会自动配置这两个类型的反序列化支持
Page
代码语言:javascript复制import com.fasterxml.jackson.databind.Module;
public class PageJacksonModule extends Module {
@Override
public String getModuleName() {
return "PageJacksonModule";
}
@Override
public Version version() {
return new Version(0, 1, 0, "", null, null);
}
@Override
public void setupModule(SetupContext context) {
// 设置模块
// 混入注解(遇到Page类型的序列化/反序列化时,按照PageMixIn类型上的注解执行)
context.setMixInAnnotations(Page.class, PageMixIn.class);
}
// 反序列化为 SimplePageImpl 类型
@JsonDeserialize(as = SimplePageImpl.class)
// 忽略未知的属性
@JsonIgnoreProperties(ignoreUnknown = true)
private interface PageMixIn {}
// 实际反序列化的类型
static class SimplePageImpl<T> implements Page<T> {
private final Page<T> delegate;
SimplePageImpl(
@JsonProperty("content")
List<T> content,
@JsonProperty("number")
int number,
@JsonProperty("size")
int size,
@JsonProperty("totalElements")
@JsonAlias({ "total-elements", "total_elements", "totalelements", "TotalElements" })
long totalElements,
@JsonProperty("sort")
Sort sort
) {
if (size > 0) {
PageRequest pageRequest;
if (sort != null) {
pageRequest = PageRequest.of(number, size, sort);
}
else {
pageRequest = PageRequest.of(number, size);
}
delegate = new PageImpl<>(content, pageRequest, totalElements);
}
else {
delegate = new PageImpl<>(content);
}
}
@JsonProperty
@Override
public int getTotalPages() {
return delegate.getTotalPages();
}
@JsonProperty
@Override
public long getTotalElements() {
return delegate.getTotalElements();
}
@JsonProperty
@Override
public int getNumber() {
return delegate.getNumber();
}
@JsonProperty
@Override
public int getSize() {
return delegate.getSize();
}
@JsonProperty
@Override
public int getNumberOfElements() {
return delegate.getNumberOfElements();
}
@JsonProperty
@Override
public List<T> getContent() {
return delegate.getContent();
}
@JsonProperty
@Override
public boolean hasContent() {
return delegate.hasContent();
}
@JsonIgnore
@Override
public Sort getSort() {
return delegate.getSort();
}
@JsonProperty
@Override
public boolean isFirst() {
return delegate.isFirst();
}
@JsonProperty
@Override
public boolean isLast() {
return delegate.isLast();
}
@JsonIgnore
@Override
public boolean hasNext() {
return delegate.hasNext();
}
@JsonIgnore
@Override
public boolean hasPrevious() {
return delegate.hasPrevious();
}
@JsonIgnore
@Override
public Pageable nextPageable() {
return delegate.nextPageable();
}
@JsonIgnore
@Override
public Pageable previousPageable() {
return delegate.previousPageable();
}
@JsonIgnore
@Override
public <S> Page<S> map(Function<? super T, ? extends S> converter) {
return delegate.map(converter);
}
@JsonIgnore
@Override
public Iterator<T> iterator() {
return delegate.iterator();
}
@JsonIgnore
@Override
public Pageable getPageable() {
return delegate.getPageable();
}
@JsonIgnore
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean equals(Object obj) {
return delegate.equals(obj);
}
@Override
public String toString() {
return delegate.toString();
}
}
}
Sort
代码语言:javascript复制import com.fasterxml.jackson.databind.Module;
public class SortJacksonModule extends Module {
@Override
public String getModuleName() {
return "SortModule";
}
@Override
public Version version() {
return new Version(0, 1, 0, "", null, null);
}
@Override
public void setupModule(SetupContext context) {
// 添加Sort类型序列化器
SimpleSerializers serializers = new SimpleSerializers();
serializers.addSerializer(Sort.class, new SortJsonComponent.SortSerializer());
context.addSerializers(serializers);
// 添加Sort类型反序列化器
SimpleDeserializers deserializers = new SimpleDeserializers();
deserializers.addDeserializer(Sort.class, new SortJsonComponent.SortDeserializer());
context.addDeserializers(deserializers);
}
}
代码语言:javascript复制public class SortJsonComponent {
// Sort类型序列化器
public static class SortSerializer extends JsonSerializer<Sort> {
@Override
public void serialize(Sort value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 序列化为Order数组格式
gen.writeStartArray();
value.iterator().forEachRemaining(v -> {
try {
gen.writeObject(v);
}
catch (IOException e) {
throw new EncodeException("Couldn't serialize object " v);
}
});
gen.writeEndArray();
}
@Override
public Class<Sort> handledType() {
return Sort.class;
}
}
// Sort类型反序列化器
public static class SortDeserializer extends JsonDeserializer<Sort> {
@Override
public Sort deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
// 解析为Order数组,再构造为Sort类型
if (treeNode.isArray()) {
ArrayNode arrayNode = (ArrayNode) treeNode;
List<Sort.Order> orders = new ArrayList<>();
for (JsonNode jsonNode : arrayNode) {
Sort.Order order = new Sort.Order(Sort.Direction.valueOf(jsonNode.get("direction").textValue()),
jsonNode.get("property").textValue());
orders.add(order);
}
return Sort.by(orders);
}
return null;
}
@Override
public Class<Sort> handledType() {
return Sort.class;
}
}
}