mirror of https://github.com/halo-dev/halo
Allow deserializing ListResult (#7711)
#### What type of PR is this? /kind improvement /area core /milestone 2.21.x #### What this PR does / why we need it: This PR allows ListResult to be deserialized with JSON. So we can resolve ListResult response of APIs correctly. #### Does this PR introduce a user-facing change? ```release-note None ```pull/7725/head
parent
4ac80f5eb3
commit
956e23dd7f
|
@ -2,6 +2,7 @@ package run.halo.app.extension;
|
||||||
|
|
||||||
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
|
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -32,7 +33,12 @@ public class ListResult<T> implements Iterable<T>, Supplier<Stream<T>> {
|
||||||
@Schema(description = "A chunk of items.", requiredMode = REQUIRED)
|
@Schema(description = "A chunk of items.", requiredMode = REQUIRED)
|
||||||
private final List<T> items;
|
private final List<T> items;
|
||||||
|
|
||||||
public ListResult(int page, int size, long total, List<T> items) {
|
@JsonCreator
|
||||||
|
public ListResult(
|
||||||
|
@JsonProperty("page") int page,
|
||||||
|
@JsonProperty("size") int size,
|
||||||
|
@JsonProperty("total") long total,
|
||||||
|
@JsonProperty("items") List<T> items) {
|
||||||
Assert.isTrue(total >= 0, "Total elements must be greater than or equal to 0");
|
Assert.isTrue(total >= 0, "Total elements must be greater than or equal to 0");
|
||||||
if (page < 0) {
|
if (page < 0) {
|
||||||
page = 0;
|
page = 0;
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package run.halo.app.extension;
|
package run.halo.app.extension;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.skyscreamer.jsonassert.JSONAssert;
|
||||||
|
|
||||||
class ListResultTest {
|
class ListResultTest {
|
||||||
|
|
||||||
|
@ -63,6 +69,66 @@ class ListResultTest {
|
||||||
assertEquals(Optional.of("A"), ListResult.first(listResult));
|
assertEquals(Optional.of("A"), ListResult.first(listResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void serializationTest() throws JsonProcessingException {
|
||||||
|
var result = new ListResult<>(1, 10, 100, List.of("a", "b", "c"));
|
||||||
|
var json = JsonMapper.builder()
|
||||||
|
.build()
|
||||||
|
.writeValueAsString(result);
|
||||||
|
JSONAssert.assertEquals("""
|
||||||
|
{
|
||||||
|
"page": 1,
|
||||||
|
"size": 10,
|
||||||
|
"total": 100,
|
||||||
|
"items": [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c"
|
||||||
|
],
|
||||||
|
"first": true,
|
||||||
|
"last": false,
|
||||||
|
"hasNext": true,
|
||||||
|
"hasPrevious": false,
|
||||||
|
"totalPages": 10
|
||||||
|
}
|
||||||
|
""", json, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deserializationTest() throws JsonProcessingException {
|
||||||
|
var json = """
|
||||||
|
{
|
||||||
|
"page": 2,
|
||||||
|
"size": 10,
|
||||||
|
"total": 100,
|
||||||
|
"items": [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c"
|
||||||
|
],
|
||||||
|
"first": false,
|
||||||
|
"last": false,
|
||||||
|
"hasNext": true,
|
||||||
|
"hasPrevious": true,
|
||||||
|
"totalPages": 10
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
var result = JsonMapper.builder()
|
||||||
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||||
|
.build()
|
||||||
|
.readValue(json, new TypeReference<ListResult<String>>() {
|
||||||
|
});
|
||||||
|
assertEquals(2, result.getPage());
|
||||||
|
assertEquals(100, result.getTotal());
|
||||||
|
assertEquals(10, result.getTotalPages());
|
||||||
|
assertEquals(10, result.getSize());
|
||||||
|
assertFalse(result.isFirst());
|
||||||
|
assertFalse(result.isLast());
|
||||||
|
assertTrue(result.hasNext());
|
||||||
|
assertTrue(result.hasPrevious());
|
||||||
|
assertEquals(List.of("a", "b", "c"), result.getItems());
|
||||||
|
}
|
||||||
|
|
||||||
private void assertSubList(List<Integer> list) {
|
private void assertSubList(List<Integer> list) {
|
||||||
var result = ListResult.subList(list, 0, 0);
|
var result = ListResult.subList(list, 0, 0);
|
||||||
assertEquals(list, result);
|
assertEquals(list, result);
|
||||||
|
|
Loading…
Reference in New Issue