Feign是Netflix出品的Java版Rest客户端,主要用于调用分布式服务
FeignPageableSupport.java
package yy.robot.bizapi.config;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Configuration
public class FeignPageableSupport {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignEncoder() {
return new PageableQueryEncoder(new SpringEncoder(messageConverters));
}
/**
* This encoder adds support for pageable, which will be applied to the query parameters.
*/
private class PageableQueryEncoder implements Encoder {
private final Encoder delegate;
PageableQueryEncoder(Encoder delegate) {
this.delegate = delegate;
}
@Override
public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
if (object instanceof Pageable) {
Pageable pageable = (Pageable) object;
template.query("page", pageable.getPageNumber() + "");
template.query("size", pageable.getPageSize() + "");
if (pageable.getSort() != null) {
Collection<String> existingSorts = template.queries().get("sort");
List<String> sortQueries = existingSorts != null ? new ArrayList<>(existingSorts) : new ArrayList<>();
for (Sort.Order order : pageable.getSort()) {
sortQueries.add(order.getProperty() + "," + order.getDirection());
}
template.query("sort", sortQueries);
}
} else {
delegate.encode(object, bodyType, template);
}
}
}
}
JacksonPageSupport
package yy.robot.bizapi.config;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.*;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.util.Iterator;
import java.util.List;
@Configuration
public class JacksonPageSupport {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
jackson2ObjectMapperBuilder.mixIn(Page.class, PageMixIn.class);
return jackson2ObjectMapperBuilder;
}
@JsonDeserialize(as = SimplePageImpl.class)
private interface PageMixIn {
}
public static class SimplePageImpl<T> implements Page<T> {
private final Page<T> delegate;
public SimplePageImpl(
@JsonProperty("content") List<T> content,
@JsonProperty("page") int number,
@JsonProperty("size") int size,
@JsonProperty("totalElements") long totalElements) {
delegate = new PageImpl<>(content, new PageRequest(number, size), totalElements);
}
@JsonProperty
@Override
public int getTotalPages() {
return delegate.getTotalPages();
}
@JsonProperty
@Override
public long getTotalElements() {
return delegate.getTotalElements();
}
@JsonProperty("page")
@Override
public int getNumber() {
return delegate.getNumber();
}
@JsonProperty
@Override
public int getSize() {
return delegate.getSize();
}
@JsonProperty
@Override
public int getNumberOfElements() {
return delegate.getNumberOfElements();
}
@JsonProperty
@Override
public List<T> getContent() {
return delegate.getContent();
}
@JsonProperty
@Override
public boolean hasContent() {
return delegate.hasContent();
}
@JsonIgnore
@Override
public Sort getSort() {
return delegate.getSort();
}
@JsonProperty
@Override
public boolean isFirst() {
return delegate.isFirst();
}
@JsonProperty
@Override
public boolean isLast() {
return delegate.isLast();
}
@JsonIgnore
@Override
public boolean hasNext() {
return delegate.hasNext();
}
@JsonIgnore
@Override
public boolean hasPrevious() {
return delegate.hasPrevious();
}
@JsonIgnore
@Override
public Pageable nextPageable() {
return delegate.nextPageable();
}
@JsonIgnore
@Override
public Pageable previousPageable() {
return delegate.previousPageable();
}
@JsonIgnore
@Override
public <S> Page<S> map(Converter<? super T, ? extends S> converter) {
return delegate.map(converter);
}
@JsonIgnore
@Override
public Iterator<T> iterator() {
return delegate.iterator();
}
}
}