Spring Pagination Data Does Not Return Results Using JSONView

I use Spring pagination data in my REST controller and returning a Paged object. I would like to manage the data returned as JSON using JSONView.

I can achieve the result when I return a single object. But when I return the page, I get empty JSON as an answer.

Below is my method signature.

@JsonView(TravelRequestView.MyRequests.class)
@RequestMapping("/travel/requests")
public Page<TravelRequest> getUserTravelRequests(
            @RequestParam("ps") int pageSize, @RequestParam("p") int page,
            @RequestParam(defaultValue = "", value = "q") String searchString)

I can get an answer when I delete @JsonView annotation.

+4
source share
6 answers

Try adding the code below.

@Configuration
public class MyInterceptorConfig extends WebMvcConfigurerAdapter{

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
      MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
      ObjectMapper mapper = new ObjectMapper() {
        private static final long serialVersionUID = 1L;
        @Override
        protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) {
          // replace the configuration with my modified configuration.
          // calling "withView" should keep previous config and just add my changes.
          return super._serializerProvider(config.withView(TravelRequestView.MyRequests.class));
        }        
      };
      mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
      converter.setObjectMapper(mapper);
      converters.add(converter);
    }

Although I do not want to take credit for this, it was a link from

Jackson JsonView not applicable

, jsonview (TravelRequestView.MyRequests.class) , jsonview. , .

+4

DEFAULT_VIEW_INCLUSION , Page. :

@Bean
public Module springDataPageModule() {
    return new SimpleModule().addSerializer(Page.class, new JsonSerializer<Page>() {
        @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();
        }
    });
}

(, ) ResponseBodyAdvice. , REST JSON HTTP- "X-Has-Next-Page", , . : 1) (*) ( ) 2) , JSON

/**
 * 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<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> 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;
    }
}
+7

spring -boot, application.yml

spring:
  jackson:
    mapper:
      DEFAULT_VIEW_INCLUSION: true

application.properties

spring.jackson.mapper.DEFAULT_VIEW_INCLUSION=true

ObjectMapper, Spring Container, ObjectMapper. , ObjectMapper Spring, , , , CustomDateSerialzer

: http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html

+4

@JsonView (TravelRequestView.MyRequests.class) . , .

public class Page<T> {
    @JsonView(TravelRequestView.MyRequests.class)
    private T view;
 ...
}

DEFAULT_VIEW_INCLUSION ObjectMapper:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="defaultViewInclusion" value="true"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

dto ,

+1

. , , , @JsonView , . JsonView. , , MyPage

public class MyPage<T> implements Page<T> {

    private Page<T> pageObj;

    public MyPage(Page<T> pageObj) {
        this.pageObj = pageObj;
    }

    @JsonView(PaginatedResult.class)
    @Override
    public int getNumber() {
        return pageObj.getNumber();
    }

    @Override
    public int getSize() {
        return pageObj.getSize();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public int getNumberOfElements() {
        return pageObj.getNumberOfElements();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public List<T> getContent() {
        return pageObj.getContent();
    }

    @Override
    public boolean hasContent() {
        return pageObj.hasContent();
    }

    @Override
    public Sort getSort() {
        return pageObj.getSort();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public boolean isFirst() {
        return pageObj.isFirst();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public boolean isLast() {
        return pageObj.isLast();
    }

    @Override
    public boolean hasNext() {
        return pageObj.hasNext();
    }

    @Override
    public boolean hasPrevious() {
        return pageObj.hasPrevious();
    }

    @Override
    public Pageable nextPageable() {
        return pageObj.nextPageable();
    }

    @Override
    public Pageable previousPageable() {
        return pageObj.previousPageable();
    }

    @Override
    public Iterator<T> iterator() {
        return pageObj.iterator();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public int getTotalPages() {
        return pageObj.getTotalPages();
    }

    @JsonView(PaginatedResult.class)
    @Override
    public long getTotalElements() {
        return pageObj.getTotalElements();
    }

}
+1

bean . , , Blans Jacker BeanSerializer: com.fasterxml.jackson.databind.ser.BeanSerializer , BeanSerializer, PageSerialier, bean Page < > DO NOT .

, :

public class MyPageSerializer extends BeanSerializer {

/**
 * MODIFIED By Gauthier PEEL
 */
@Override
protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider)
        throws IOException, JsonGenerationException {
    final BeanPropertyWriter[] props;
    // ADDED
    // ADDED
    // ADDED
    if (bean instanceof Page) {
        // for Page DO NOT filter anything so that @JsonView is passthrough at this level
        props = _props;
    } else {
        // ADDED
        // ADDED
        if (_filteredProps != null && provider.getActiveView() != null) {
            props = _filteredProps;
        } else {
            props = _props;
        }
    }

        // rest of the method unchanged
    }

    // inherited constructor removed for concision
}

:

public class MyPageModule extends SimpleModule {

    @Override
    public void setupModule(SetupContext context) {

        context.addBeanSerializerModifier(new BeanSerializerModifier() {

            @Override
            public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc,
                    JsonSerializer<?> serializer) {
                if (serializer instanceof BeanSerializerBase) {
                    return new MyPageSerializer ((BeanSerializerBase) serializer);
                }
                return serializer;

            }
        });
    }
}

Spring conf : @Configuration @ Bean MyPageModule

@Configuration
public class WebConfigPage extends WebMvcConfigurerAdapter {

    /**
     * To enable Jackson @JsonView to work with Page<T>
     */
    @Bean
    public MyPageModule myPageModule() {
        return new MyPageModule();
    }

}

.

0

All Articles