前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring-data Page/Sort类型 jackson序列化模块

spring-data Page/Sort类型 jackson序列化模块

作者头像
路过君
发布2024-05-24 12:24:10
340
发布2024-05-24 12:24:10
举报

版本

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;
		}
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 版本
  • 问题
  • Page
  • Sort
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档