SpringMvcContract support parse params (#1016)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -87,6 +87,7 @@ import static org.springframework.core.annotation.AnnotatedElementUtils.findMerg
|
||||
* @author Darren Foong
|
||||
* @author Ram Anaswara
|
||||
* @author Sam Kruglov
|
||||
* @author Tang Xiong
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract implements ResourceLoaderAware {
|
||||
|
||||
@@ -244,6 +245,9 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
// headers
|
||||
parseHeaders(data, method, methodMapping);
|
||||
|
||||
// params
|
||||
parseParams(data, method, methodMapping);
|
||||
|
||||
data.indexToExpander(new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
@@ -354,6 +358,22 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
}
|
||||
}
|
||||
|
||||
private void parseParams(MethodMetadata data, Method method, RequestMapping methodMapping) {
|
||||
String[] params = methodMapping.params();
|
||||
if (params == null || params.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (String param : params) {
|
||||
NameValueResolver nameValueResolver = new NameValueResolver(param);
|
||||
if (!nameValueResolver.isNegated()) {
|
||||
data.template().query(resolve(nameValueResolver.getName()), resolve(nameValueResolver.getValue()));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Negated params are not supported: " + param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Class<? extends Annotation>, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(
|
||||
List<AnnotatedParameterProcessor> processors) {
|
||||
Map<Class<? extends Annotation>, AnnotatedParameterProcessor> result = new HashMap<>();
|
||||
@@ -465,4 +485,40 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
|
||||
}
|
||||
|
||||
private static class NameValueResolver {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String value;
|
||||
|
||||
private final boolean isNegated;
|
||||
|
||||
NameValueResolver(String expression) {
|
||||
int separator = expression.indexOf('=');
|
||||
if (separator == -1) {
|
||||
isNegated = expression.startsWith("!");
|
||||
name = (isNegated ? expression.substring(1) : expression);
|
||||
value = null;
|
||||
}
|
||||
else {
|
||||
isNegated = (separator > 0) && (expression.charAt(separator - 1) == '!');
|
||||
name = (isNegated ? expression.substring(0, separator - 1) : expression.substring(0, separator));
|
||||
value = expression.substring(separator + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isNegated() {
|
||||
return isNegated;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
* Copyright 2013-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -82,6 +82,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
* @author Szymon Linowski
|
||||
* @author Sam Kruglov
|
||||
* @author Bhavya Agrawal
|
||||
* @author Tang Xiong
|
||||
**/
|
||||
|
||||
class SpringMvcContractTests {
|
||||
@@ -462,6 +463,68 @@ class SpringMvcContractTests {
|
||||
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_SingleParam() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("singleParam");
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1=1");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_MultipleParams() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("multipleParams");
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1=1&p2=2");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_MixParams() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("mixParams");
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1=1&p2");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_SingleParamWithoutValue() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("singleParamWithoutValue");
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_MultipleParamsWithoutValue() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("multipleParamsWithoutValue");
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1&p2");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_NotEqualParams() throws Exception {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("notEqualParams");
|
||||
contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessAnnotations_ParseParams_ParamsAndRequestParam() throws Exception {
|
||||
Method method = TestTemplate_ParseParams.class.getDeclaredMethod("paramsAndRequestParam", String.class);
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
|
||||
assertThat(data.template().url()).isEqualTo("/test?p1=1&p2={p2}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProcessHeaders() throws Exception {
|
||||
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", String.class);
|
||||
@@ -750,6 +813,31 @@ class SpringMvcContractTests {
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_ParseParams {
|
||||
|
||||
@GetMapping(value = "test", params = "p1=1")
|
||||
ResponseEntity<TestObject> singleParam();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1=1", "p2=2" })
|
||||
ResponseEntity<TestObject> multipleParams();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1" })
|
||||
ResponseEntity<TestObject> singleParamWithoutValue();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1", "p2" })
|
||||
ResponseEntity<TestObject> multipleParamsWithoutValue();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1=1", "p2" })
|
||||
ResponseEntity<TestObject> mixParams();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1!=1" })
|
||||
ResponseEntity<TestObject> notEqualParams();
|
||||
|
||||
@GetMapping(value = "test", params = { "p1=1" })
|
||||
ResponseEntity<TestObject> paramsAndRequestParam(@RequestParam("p2") String p2);
|
||||
|
||||
}
|
||||
|
||||
public interface TestTemplate_HeaderMap {
|
||||
|
||||
@GetMapping("/headerMap")
|
||||
|
||||
Reference in New Issue
Block a user