Skip to content

Commit 87f95e8

Browse files
committed
When oneIndexedParameters is set to true, respect that setting when serializing PageImpl
1 parent f305308 commit 87f95e8

File tree

3 files changed

+77
-11
lines changed

3 files changed

+77
-11
lines changed

Diff for: src/main/java/org/springframework/data/web/PagedModel.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,27 @@
3333
*
3434
* @author Oliver Drotbohm
3535
* @author Greg Turnquist
36+
* @author Lazar Radinović
3637
* @since 3.3
3738
*/
3839
public class PagedModel<T> {
3940

4041
private final Page<T> page;
4142

43+
private final boolean oneIndexedParameters;
44+
4245
/**
4346
* Creates a new {@link PagedModel} for the given {@link Page}.
4447
*
45-
* @param page must not be {@literal null}.
48+
* @param page must not be {@literal null}.
49+
* @param oneIndexedParameters indicates weather to serialize page number by adding 0 or 1
4650
*/
47-
public PagedModel(Page<T> page) {
51+
public PagedModel(Page<T> page, boolean oneIndexedParameters) {
4852

4953
Assert.notNull(page, "Page must not be null");
5054

5155
this.page = page;
56+
this.oneIndexedParameters = oneIndexedParameters;
5257
}
5358

5459
@JsonProperty
@@ -59,7 +64,7 @@ public List<T> getContent() {
5964
@Nullable
6065
@JsonProperty("page")
6166
public PageMetadata getMetadata() {
62-
return new PageMetadata(page.getSize(), page.getNumber(), page.getTotalElements(),
67+
return new PageMetadata(page.getSize(), page.getNumber() + (oneIndexedParameters ? 1 : 0), page.getTotalElements(),
6368
page.getTotalPages());
6469
}
6570

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.springframework.data.web.config;
2+
3+
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
4+
5+
/**
6+
* Callback interface that can be implemented by beans wishing to customize the
7+
* {@link SpringDataJacksonConfiguration.PageModule} configuration.
8+
*
9+
* @author Lazar Radinović
10+
* @since 3.4.0
11+
*/
12+
public interface PageModuleCustomizer {
13+
/**
14+
* Customize the given {@link SpringDataJacksonConfiguration.PageModule}.
15+
*
16+
* @param pageModule the {@link SpringDataJacksonConfiguration.PageModule} to customize, will never be {@literal null}.
17+
*/
18+
void customize(SpringDataJacksonConfiguration.PageModule pageModule);
19+
}

Diff for: src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java

+50-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.web.config;
1717

18+
import java.io.IOException;
1819
import java.util.List;
1920

2021
import org.slf4j.Logger;
@@ -31,12 +32,14 @@
3132

3233
import com.fasterxml.jackson.databind.BeanDescription;
3334
import com.fasterxml.jackson.databind.SerializationConfig;
34-
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
3535
import com.fasterxml.jackson.databind.module.SimpleModule;
3636
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
3737
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
3838
import com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase;
3939
import com.fasterxml.jackson.databind.util.StdConverter;
40+
import com.fasterxml.jackson.core.JsonGenerator;
41+
import com.fasterxml.jackson.databind.JsonSerializer;
42+
import com.fasterxml.jackson.databind.SerializerProvider;
4043

4144
/**
4245
* JavaConfig class to export Jackson specific configuration.
@@ -53,8 +56,12 @@ public GeoModule jacksonGeoModule() {
5356
}
5457

5558
@Bean
56-
public PageModule pageModule() {
57-
return new PageModule(settings);
59+
public PageModule pageModule(@Autowired(required = false) PageModuleCustomizer customizer) {
60+
PageModule module = new PageModule(settings);
61+
if(customizer != null) {
62+
customizer.customize(module);
63+
}
64+
return module;
5865
}
5966

6067
/**
@@ -79,6 +86,9 @@ public static class PageModule extends SimpleModule {
7986
UNPAGED_TYPE = ClassUtils.resolveClassName(UNPAGED_TYPE_NAME, PageModule.class.getClassLoader());
8087
}
8188

89+
private boolean oneIndexedParameters;
90+
private PageModelConverter pageModelConverter;
91+
8292
/**
8393
* Creates a new {@link PageModule} for the given {@link SpringDataWebSettings}.
8494
*
@@ -92,10 +102,39 @@ public PageModule(@Nullable SpringDataWebSettings settings) {
92102
setSerializerModifier(new WarningLoggingModifier());
93103

94104
} else {
95-
setMixInAnnotation(PageImpl.class, WrappingMixing.class);
105+
pageModelConverter = new PageModelConverter();
106+
addSerializer(PageImpl.class, new JsonSerializer<>() {
107+
@Override
108+
public void serialize(PageImpl page, JsonGenerator gen, SerializerProvider providers) throws IOException {
109+
gen.writeObject(pageModelConverter.convert(page));
110+
}
111+
});
96112
}
97113
}
98114

115+
/**
116+
* Configures whether to expose and assume 1-based page number indexes in the request parameters. Defaults to
117+
* {@literal false}, meaning a page number of 0 in the request equals the first page. If this is set to
118+
* {@literal true}, a page number of 1 in the request will be considered the first page.
119+
*
120+
* @param oneIndexedParameters the oneIndexedParameters to set
121+
*/
122+
public void setOneIndexedParameters(boolean oneIndexedParameters) {
123+
this.oneIndexedParameters = oneIndexedParameters;
124+
this.pageModelConverter.setOneIndexedParameters(oneIndexedParameters);
125+
}
126+
127+
/**
128+
* Indicates whether to expose and assume 1-based page number indexes in the request parameters. Defaults to
129+
* {@literal false}, meaning a page number of 0 in the request equals the first page. If this is set to
130+
* {@literal true}, a page number of 1 in the request will be considered the first page.
131+
*
132+
* @return whether to assume 1-based page number indexes in the request parameters.
133+
*/
134+
public boolean isOneIndexedParameters() {
135+
return oneIndexedParameters;
136+
}
137+
99138
/**
100139
* A Jackson serializer rendering instances of {@link org.springframework.data.domain.Unpaged} as {@code INSTANCE}
101140
* as it was previous rendered.
@@ -116,15 +155,18 @@ public String valueToString(@Nullable Object value) {
116155
}
117156
}
118157

119-
@JsonSerialize(converter = PageModelConverter.class)
120-
abstract class WrappingMixing {}
121-
122158
static class PageModelConverter extends StdConverter<Page<?>, PagedModel<?>> {
123159

160+
public boolean oneIndexedParameters;
161+
162+
public void setOneIndexedParameters(boolean oneIndexedParameters) {
163+
this.oneIndexedParameters = oneIndexedParameters;
164+
}
165+
124166
@Nullable
125167
@Override
126168
public PagedModel<?> convert(@Nullable Page<?> value) {
127-
return value == null ? null : new PagedModel<>(value);
169+
return value == null ? null : new PagedModel<>(value, oneIndexedParameters);
128170
}
129171
}
130172

0 commit comments

Comments
 (0)