Reject multiple @⁠HttpExchange declarations in MVC and WebFlux

This commit updates the RequestMappingHandlerMapping implementations in
Spring MVC and Spring WebFlux so that multiple @⁠HttpExchange
declarations on the same element are rejected.

Closes gh-32049
This commit is contained in:
Sam Brannen
2024-01-18 15:27:12 +01:00
parent c5c77b93fe
commit b8b31ff8a1
4 changed files with 129 additions and 6 deletions

View File

@@ -48,10 +48,12 @@ import org.springframework.web.reactive.result.condition.PatternsRequestConditio
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.Mockito.mock;
/**
@@ -154,6 +156,38 @@ class RequestMappingHandlerMappingTests {
assertComposedAnnotationMapping(RequestMethod.PATCH);
}
@Test // gh-32049
void httpExchangeWithMultipleAnnotationsAtClassLevel() throws NoSuchMethodException {
this.handlerMapping.afterPropertiesSet();
Class<?> controllerClass = MultipleClassLevelAnnotationsHttpExchangeController.class;
Method method = controllerClass.getDeclaredMethod("post");
assertThatIllegalStateException()
.isThrownBy(() -> this.handlerMapping.getMappingForMethod(method, controllerClass))
.withMessageContainingAll(
"Multiple @HttpExchange annotations found on " + controllerClass,
"@" + HttpExchange.class.getName(),
"@" + ExtraHttpExchange.class.getName()
);
}
@Test // gh-32049
void httpExchangeWithMultipleAnnotationsAtMethodLevel() throws NoSuchMethodException {
this.handlerMapping.afterPropertiesSet();
Class<?> controllerClass = MultipleMethodLevelAnnotationsHttpExchangeController.class;
Method method = controllerClass.getDeclaredMethod("post");
assertThatIllegalStateException()
.isThrownBy(() -> this.handlerMapping.getMappingForMethod(method, controllerClass))
.withMessageContainingAll(
"Multiple @HttpExchange annotations found on " + method,
"@" + PostExchange.class.getName(),
"@" + PutExchange.class.getName()
);
}
@SuppressWarnings("DataFlowIssue")
@Test
void httpExchangeWithDefaultValues() throws NoSuchMethodException {
@@ -313,4 +347,27 @@ class RequestMappingHandlerMappingTests {
public void customValuesExchange(){}
}
@HttpExchange("/exchange")
@ExtraHttpExchange
static class MultipleClassLevelAnnotationsHttpExchangeController {
@PostExchange("/post")
void post() {}
}
static class MultipleMethodLevelAnnotationsHttpExchangeController {
@PostExchange("/post")
@PutExchange("/post")
void post() {}
}
@HttpExchange
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ExtraHttpExchange {
}
}