Skip to content

Commit ca111e1

Browse files
author
puppy4c
committed
pringMvcContract support parse params
1 parent 6084609 commit ca111e1

File tree

2 files changed

+133
-2
lines changed

2 files changed

+133
-2
lines changed

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2023 the original author or authors.
2+
* Copyright 2013-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -87,6 +87,7 @@
8787
* @author Darren Foong
8888
* @author Ram Anaswara
8989
* @author Sam Kruglov
90+
* @author Tang Xiong
9091
*/
9192
public class SpringMvcContract extends Contract.BaseContract implements ResourceLoaderAware {
9293

@@ -244,6 +245,9 @@ protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodA
244245
// headers
245246
parseHeaders(data, method, methodMapping);
246247

248+
// params
249+
parseParams(data, method, methodMapping);
250+
247251
data.indexToExpander(new LinkedHashMap<>());
248252
}
249253

@@ -354,6 +358,19 @@ private void parseHeaders(MethodMetadata md, Method method, RequestMapping annot
354358
}
355359
}
356360

361+
private void parseParams(MethodMetadata data, Method method, RequestMapping methodMapping) {
362+
String[] params = methodMapping.params();
363+
if (params == null || params.length == 0) {
364+
return;
365+
}
366+
for (String param : params) {
367+
NameValueResolver nameValueResolver = new NameValueResolver(param);
368+
if (!nameValueResolver.isNegated()) {
369+
data.template().query(resolve(nameValueResolver.getName()), resolve(nameValueResolver.getValue()));
370+
}
371+
}
372+
}
373+
357374
private Map<Class<? extends Annotation>, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(
358375
List<AnnotatedParameterProcessor> processors) {
359376
Map<Class<? extends Annotation>, AnnotatedParameterProcessor> result = new HashMap<>();
@@ -465,4 +482,41 @@ public Collection<String> setTemplateParameter(String name, Collection<String> r
465482

466483
}
467484

485+
private static class NameValueResolver {
486+
487+
private final String name;
488+
489+
private final String value;
490+
491+
private final boolean isNegated;
492+
493+
NameValueResolver(String expression) {
494+
int separator = expression.indexOf('=');
495+
if (separator == -1) {
496+
this.isNegated = expression.startsWith("!");
497+
this.name = (this.isNegated ? expression.substring(1) : expression);
498+
this.value = null;
499+
}
500+
else {
501+
this.isNegated = (separator > 0) && (expression.charAt(separator - 1) == '!');
502+
this.name = (this.isNegated ? expression.substring(0, separator - 1)
503+
: expression.substring(0, separator));
504+
this.value = expression.substring(separator + 1);
505+
}
506+
}
507+
508+
public String getName() {
509+
return name;
510+
}
511+
512+
public String getValue() {
513+
return value;
514+
}
515+
516+
public boolean isNegated() {
517+
return isNegated;
518+
}
519+
520+
}
521+
468522
}

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

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2023 the original author or authors.
2+
* Copyright 2013-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,6 +82,7 @@
8282
* @author Szymon Linowski
8383
* @author Sam Kruglov
8484
* @author Bhavya Agrawal
85+
* @author Tang Xiong
8586
**/
8687

8788
class SpringMvcContractTests {
@@ -462,6 +463,60 @@ void testProcessAnnotations_MapParams() throws Exception {
462463
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
463464
}
464465

466+
@Test
467+
void testProcessAnnotations_ParseParams_SingleParam() throws Exception {
468+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("singleParam");
469+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
470+
471+
assertThat(data.template().url()).isEqualTo("/test?p1=1");
472+
assertThat(data.template().method()).isEqualTo("GET");
473+
}
474+
475+
@Test
476+
void testProcessAnnotations_ParseParams_MultipleParams() throws Exception {
477+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("multipleParams");
478+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
479+
480+
assertThat(data.template().url()).isEqualTo("/test?p1=1&p2=2");
481+
assertThat(data.template().method()).isEqualTo("GET");
482+
}
483+
484+
@Test
485+
void testProcessAnnotations_ParseParams_MixParams() throws Exception {
486+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("mixParams");
487+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
488+
489+
assertThat(data.template().url()).isEqualTo("/test?p1=1&p2");
490+
assertThat(data.template().method()).isEqualTo("GET");
491+
}
492+
493+
@Test
494+
void testProcessAnnotations_ParseParams_SingleParamWithoutValue() throws Exception {
495+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("singleParamWithoutValue");
496+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
497+
498+
assertThat(data.template().url()).isEqualTo("/test?p1");
499+
assertThat(data.template().method()).isEqualTo("GET");
500+
}
501+
502+
@Test
503+
void testProcessAnnotations_ParseParams_MultipleParamsWithoutValue() throws Exception {
504+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("multipleParamsWithoutValue");
505+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
506+
507+
assertThat(data.template().url()).isEqualTo("/test?p1&p2");
508+
assertThat(data.template().method()).isEqualTo("GET");
509+
}
510+
511+
@Test
512+
void testProcessAnnotations_ParseParams_NotEqualParams() throws Exception {
513+
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("notEqualParams");
514+
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
515+
516+
assertThat(data.template().url()).isEqualTo("/test");
517+
assertThat(data.template().method()).isEqualTo("GET");
518+
}
519+
465520
@Test
466521
void testProcessHeaders() throws Exception {
467522
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", String.class);
@@ -750,6 +805,28 @@ public interface TestTemplate_MapParams {
750805

751806
}
752807

808+
public interface TestTemplate_ParseParams {
809+
810+
@GetMapping(value = "test", params = "p1=1")
811+
ResponseEntity<TestObject> singleParam();
812+
813+
@GetMapping(value = "test", params = { "p1=1", "p2=2" })
814+
ResponseEntity<TestObject> multipleParams();
815+
816+
@GetMapping(value = "test", params = { "p1" })
817+
ResponseEntity<TestObject> singleParamWithoutValue();
818+
819+
@GetMapping(value = "test", params = { "p1", "p2" })
820+
ResponseEntity<TestObject> multipleParamsWithoutValue();
821+
822+
@GetMapping(value = "test", params = { "p1=1", "p2" })
823+
ResponseEntity<TestObject> mixParams();
824+
825+
@GetMapping(value = "test", params = { "p1!=1" })
826+
ResponseEntity<TestObject> notEqualParams();
827+
828+
}
829+
753830
public interface TestTemplate_HeaderMap {
754831

755832
@GetMapping("/headerMap")

0 commit comments

Comments
 (0)