All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.web.servlet.mvc.method.annotation.PageResponseBodyAdvice Maven / Gradle / Ivy

package org.springframework.web.servlet.mvc.method.annotation;

import java.lang.reflect.Field;
import java.util.List;

import org.springframework.core.MethodParameter;
import org.springframework.data.domain.OffsetRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImplCustom;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Persistable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.querydsl.QSort;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.NumberUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;

@ControllerAdvice
public class PageResponseBodyAdvice extends org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice {
  /**
   * @see ServletUriComponentsBuilder#fromCurrentRequest()
   */
  @Override
  protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType, MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response) {
    Object value = bodyContainer.getValue();
    if (value instanceof Page) {
      Field field = ReflectionUtils.findField(value.getClass(), "pageable");
      if (field != null) {
        ReflectionUtils.makeAccessible(field);
        Object pageable = ReflectionUtils.getField(field, value);
        if (pageable instanceof Pageable) {
          pageable = getPageable((Pageable) pageable);
          value = getPage((Page) value, (Pageable) pageable, UriComponentsBuilder.fromHttpRequest(request));
          if (pageable instanceof OffsetRequest) {
            value = getPage((Page) value, (OffsetRequest) pageable, field);
          }
          bodyContainer.setValue(value);
        }
      }
    }
  }

  private Page getPage(Page page, Pageable pageable, UriComponentsBuilder builder) {
    if (page instanceof PageImplCustom) {
      return page;
    }
    return new PageImplCustom<>(page.getContent(), pageable, page.getTotalElements(), builder);
  }

  private Pageable getPageable(Pageable pageable) {
    Field field = ReflectionUtils.findField(pageable.getClass(), "sort");
    if (field != null) {
      ReflectionUtils.makeAccessible(field);
      Object sort = ReflectionUtils.getField(field, pageable);
      if (sort instanceof QSort) {
        Sort value = null;
        for (Order order : ((QSort) sort)) {
          value = value == null ? new Sort(order) : value.and(new Sort(order));
        }
        ReflectionUtils.setField(field, pageable, value);
      }
    }
    return pageable;
  }

  /**
   * 
   * int first = (s = content.stream().reduce((start, end) -> start).orElse(null)) != null && s.getId() instanceof Number ? ((Number) s.getId()).intValue() : pageable.getFlag();
   * int last = (s = content.stream().reduce((start, end) -> end).orElse(null)) != null && s.getId() instanceof Number ? ((Number) s.getId()).intValue() : pageable.getFlag();
   * 
*/ private Page getPage(Page page, OffsetRequest pageable, Field field) { List content = page.getContent(); if (pageable.hasDirection() && ClassUtils.isAssignable(Persistable.class, CollectionUtils.findCommonElementType(content))) { Persistable persistable; boolean empty = CollectionUtils.isEmpty(content); int first = !empty && (persistable = (Persistable) content.get(0)) != null && persistable.getId() instanceof Number ? NumberUtils.convertNumberToTargetClass((Number) persistable.getId(), Integer.class) : pageable.getId(); int last = !empty && (persistable = (Persistable) content.get(content.size() - 1)) != null && persistable.getId() instanceof Number ? NumberUtils.convertNumberToTargetClass((Number) persistable.getId(), Integer.class) : pageable.getId(); pageable.setFirst(first); pageable.setLast(last); pageable.setDirection(first < last ? Direction.ASC : Direction.DESC); ReflectionUtils.setField(field, page, pageable); } return page; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy