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

2024-05-24 12:24:10 浏览数 (3)

版本

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;
		}
	}
}

0 人点赞