Spring Data Pagination returns no results with JSONView

后端 未结 6 1538
广开言路
广开言路 2021-02-06 02:53

I am using Spring data pagination in my REST Controller and returning Paged entity. I would like to control the data returned as JSON with the help of JSONViews.

I am a

6条回答
  •  北荒
    北荒 (楼主)
    2021-02-06 03:32

    Setting DEFAULT_VIEW_INCLUSION has a global effect, while all we need is to be able to serialize a Page object. The following code will register a serializer for Page, and is a simple change to your code:

    @Bean
    public Module springDataPageModule() {
        return new SimpleModule().addSerializer(Page.class, new JsonSerializer() {
            @Override
            public void serialize(Page value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeStartObject();
                gen.writeNumberField("totalElements",value.getTotalElements());
                gen.writeNumberField("totalPages", value.getTotalPages());
                gen.writeNumberField("number", value.getNumber());
                gen.writeNumberField("size", value.getSize());
                gen.writeBooleanField("first", value.isFirst());
                gen.writeBooleanField("last", value.isLast());
                gen.writeFieldName("content");
                serializers.defaultSerializeValue(value.getContent(),gen);
                gen.writeEndObject();
            }
        });
    }
    

    Another (arguably more elegant) solution is to register the following ResponseBodyAdvice. It will make sure your REST endpoint will still return a JSON array, and set a HTTP header 'X-Has-Next-Page' to indicate whether there is more data. The advantages are: 1) No extra count(*) query to your DB (single query) 2) Response is more elegant, since it returns a JSON array

    /**
     * ResponseBodyAdvice to support Spring data Slice object in JSON responses.
     * If the value is a slice, we'll write the List as an array, and add a header to the HTTP response
     *
     * @author blagerweij
     */
    @ControllerAdvice
    public class SliceResponseBodyAdvice implements ResponseBodyAdvice {
    
        @Override
        public boolean supports(MethodParameter returnType, Class> converterType) {
            return true;
        }
    
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            if (body instanceof Slice) {
                Slice slice = (Slice) body;
                response.getHeaders().add("X-Has-Next-Page", String.valueOf(slice.hasNext()));
                return slice.getContent();
            }
            return body;
        }
    }
    
        

    提交回复
    热议问题