Browse Source

Fix pageable processing when querymap present.

fix-pageable-processing-when-querymap-present
Olga Maciaszek-Sharma 2 years ago
parent
commit
a8bcc5c4ed
  1. 33
      spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/SpringMvcContract.java
  2. 26
      spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java

33
spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/SpringMvcContract.java

@ -34,12 +34,14 @@ import feign.Contract; @@ -34,12 +34,14 @@ import feign.Contract;
import feign.Feign;
import feign.MethodMetadata;
import feign.Param;
import feign.QueryMap;
import feign.Request;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.CollectionFormat;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.cloud.openfeign.annotation.CookieValueParameterProcessor;
import org.springframework.cloud.openfeign.annotation.MatrixVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor;
@ -67,6 +69,7 @@ import org.springframework.util.Assert; @@ -67,6 +69,7 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
@ -158,7 +161,7 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource @@ -158,7 +161,7 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
private static TypeDescriptor getElementTypeDescriptor(TypeDescriptor typeDescriptor) {
TypeDescriptor elementTypeDescriptor = typeDescriptor.getElementTypeDescriptor();
// that means it's not a collection but it is iterable, gh-135
// that means it's not a collection, but it is iterable, gh-135
if (elementTypeDescriptor == null && Iterable.class.isAssignableFrom(typeDescriptor.getType())) {
ResolvableType type = typeDescriptor.getResolvableType().as(Iterable.class).getGeneric(0);
if (type.resolve() == null) {
@ -268,8 +271,12 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource @@ -268,8 +271,12 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
try {
if (Pageable.class.isAssignableFrom(data.method().getParameterTypes()[paramIndex])) {
data.queryMapIndex(paramIndex);
return false;
// do not set a Pageable as QueryMap if there's an actual QueryMap param
// present
if (!queryMapParamPresent(data)) {
data.queryMapIndex(paramIndex);
return false;
}
}
}
catch (NoClassDefFoundError ignored) {
@ -292,7 +299,11 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource @@ -292,7 +299,11 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
}
}
if (!isMultipartFormData(data) && isHttpAnnotation && data.indexToExpander().get(paramIndex) == null) {
if (!
isMultipartFormData(data) && isHttpAnnotation && data.indexToExpander().
get(paramIndex) == null) {
TypeDescriptor typeDescriptor = createTypeDescriptor(method, paramIndex);
if (conversionService.canConvert(typeDescriptor, STRING_TYPE_DESCRIPTOR)) {
Param.Expander expander = convertingExpanderFactory.getExpander(typeDescriptor);
@ -304,6 +315,20 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource @@ -304,6 +315,20 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
return isHttpAnnotation;
}
private boolean queryMapParamPresent(MethodMetadata data) {
Annotation[][] paramsAnnotations = data.method().getParameterAnnotations();
for (int i = 0; i < paramsAnnotations.length; i++) {
Annotation[] paramAnnotations = paramsAnnotations[i];
Class<?> parameterType = data.method().getParameterTypes()[i];
if (Arrays.stream(paramAnnotations).anyMatch(
annotation -> Map.class.isAssignableFrom(parameterType) && annotation instanceof RequestParam
|| annotation instanceof SpringQueryMap || annotation instanceof QueryMap)) {
return true;
}
}
return false;
}
private void parseProduces(MethodMetadata md, Method method, RequestMapping annotation) {
String[] serverProduces = annotation.produces();
String clientAccepts = serverProduces.length == 0 ? null : emptyToNull(serverProduces[0]);

26
spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java

@ -117,7 +117,7 @@ class SpringMvcContractTests { @@ -117,7 +117,7 @@ class SpringMvcContractTests {
Method isNamePresent = ReflectionUtils.findMethod(parameters[0].getClass(), "isNamePresent");
return Boolean.TRUE.equals(isNamePresent.invoke(parameters[0]));
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ignored) {
}
}
return false;
@ -631,10 +631,20 @@ class SpringMvcContractTests { @@ -631,10 +631,20 @@ class SpringMvcContractTests {
void shouldNotFailWhenBothPageableAndRequestBodyParamsInPostRequest() {
List<MethodMetadata> data = contract.parseAndValidateMetadata(TestTemplate_PageablePost.class);
assertThat(data.get(0).queryMapIndex().intValue()).isEqualTo(0);
assertThat(data.get(0).bodyIndex().intValue()).isEqualTo(1);
assertThat(data.get(1).queryMapIndex().intValue()).isEqualTo(1);
assertThat(data.get(1).bodyIndex().intValue()).isEqualTo(0);
assertThat(data.get(2).queryMapIndex()).isEqualTo(1);
assertThat(data.get(2).bodyIndex()).isEqualTo(0);
assertThat(data.get(3).queryMapIndex()).isEqualTo(0);
assertThat(data.get(3).bodyIndex()).isEqualTo(1);
}
@Test
void shouldSetPageableAsBodyWhenQueryMapParamPresent() {
List<MethodMetadata> data = contract.parseAndValidateMetadata(TestTemplate_PageablePost.class);
assertThat(data.get(0).queryMapIndex()).isEqualTo(1);
assertThat(data.get(0).bodyIndex()).isEqualTo(0);
assertThat(data.get(1).queryMapIndex()).isEqualTo(0);
assertThat(data.get(1).bodyIndex()).isEqualTo(1);
}
private ConversionService getConversionService() {
@ -846,6 +856,12 @@ class SpringMvcContractTests { @@ -846,6 +856,12 @@ class SpringMvcContractTests {
@PostMapping
Page<String> getPage(@RequestBody String body, Pageable pageable);
@PostMapping
Page<String> getPage(@SpringQueryMap TestObject pojo, Pageable pageable);
@PostMapping
Page<String> getPage(Pageable pageable, @SpringQueryMap TestObject pojo);
}
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)

Loading…
Cancel
Save