PageImp无法序列化问题
问题解决
2020-04-05
88
0
问题
使用Spring data的Page进行分页之后,在缓存的时候发生无法序列化的问题,原因是PageImp没有无参构造函数,而GenericJackson2JsonRedisSerializer在反序列化的时候针对空值情况需要使用无餐构造函数
ERROR: Could not read JSON: Cannot construct instance of `org.springframework.data.domain.PageImpl` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
解决
-
要么改用本地缓存,cachetype设置为simple等(逃避
-
要么自定义序列化器
-
要么更改序列化器
JdkSerializationRedisSerializer,通用型较好,但是效率较低,占用空间更大,并且序列化后是二进制数组,可读性较差
或者使用FST、Kryo,性能会更高,Kryo线程不安全,还需要自己registry对象
有关序列化器选型:https://my.oschina.net/wangshuhui/blog/3144798
对比测试:https://gitee.com/SoftMeng/spring-boot-skill/tree/master/redis-serializer-line
- 要么自定义一个有无餐构造的page类(要把用到page的地方都重构,有点痛苦)
通用的自定义Page类:(这里可以用装饰器模式)
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class MyPage<T> implements Iterable<T>, Serializable {
private static final long serialVersionUID = -2295910683371889666L;
private List<T> content = new ArrayList<>();
private long totalElements;
private int pageNumber;
private int pageSize;
private boolean first;
private boolean last;
private boolean empty;
private int totalPages;
private int numberOfElements;
private Sort sort;
public MyPage() {
}
/**
* 原Page转换为MyPage
* @param page
*/
public MyPage(Page<T> page) {
this.content = page.getContent();
this.totalElements = page.getTotalElements();
this.pageNumber = page.getPageable().getPageNumber();
this.pageSize = page.getPageable().getPageSize();
this.numberOfElements = page.getNumberOfElements();
this.sort = page.getSort();
}
/**
* 是否有前一页
* @return
*/
public boolean hasPrevious() {
return getPageNumber() > 0;
}
/**
* 是否有下一页
* @return
*/
public boolean hasNext() {
return getPageNumber() + 1 < getTotalPages();
}
/**
* 是否第一页
* @return
*/
public boolean isFirst() {
return !hasPrevious();
}
/**
* 是否最后一页
* @return
*/
public boolean isLast() {
return !hasNext();
}
/**
* 获取内容
* @return
*/
public List<T> getContent() {
return Collections.unmodifiableList(content);
}
/**
* 设置内容
*/
public void setContent(List<T> content) {
this.content = content;
}
/**
* 是否有内容
* @return
*/
public boolean hasContent() {
return getNumberOfElements() > 0;
}
/**
* 获取单页大小
* @return
*/
public int getPageSize() {
return pageSize;
}
/**
* 设置单页大小
* @param pageSize
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
* 获取全部元素数目
* @return
*/
public long getTotalElements() {
return totalElements;
}
/**
* 设置全部元素数目
* @param totalElements
*/
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
/**
* 设置是否第一页
* @param first
*/
public void setFirst(boolean first) {
this.first = first;
}
/**
* 设置是否最后一页
* @param last
*/
public void setLast(boolean last) {
this.last = last;
}
/**
* 获取当前页号
* @return
*/
public int getPageNumber() {
return pageNumber;
}
/**
* 设置当前页号
* @param pageNumber
*/
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
/**
* 获取总页数
* @return
*/
public int getTotalPages() {
return getPageSize() == 0 ? 1 : (int) Math.ceil((double) totalElements / (double) getPageSize());
}
/**
* 设置总页数
* @param totalPages
*/
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
/**
* 获取单页元素数目
* @return
*/
public int getNumberOfElements() {
return numberOfElements;
}
/**
* 设置单页元素数目
* @param numberOfElements
*/
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
/**
* 获得Sort
* @return
*/
public Sort getSort() {
return sort;
}
/**
* 设置Sort
* @param sort
*/
public void setSort(Sort sort) {
this.sort = sort;
}
/**
* 判断是否为空
* @return
*/
public boolean isEmpty() {
return !hasContent();
}
/**
* 设置是否为空
* @param empty
*/
public void setEmpty(boolean empty) {
this.empty = empty;
}
/**
* 迭代器
* @return
*/
@Override
public Iterator<T> iterator() {
return getContent().iterator();
}
}
0条评论