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,6 +48,7 @@ import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.method.HandlerTypePredicate;
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.servlet.handler.PathPatternsParameterizedTest;
import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
import org.springframework.web.servlet.mvc.condition.MediaTypeExpression;
@@ -58,6 +59,7 @@ 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;
/**
@@ -276,6 +278,38 @@ class RequestMappingHandlerMappingTests {
assertComposedAnnotationMapping(RequestMethod.PATCH);
}
@Test // gh-32049
void httpExchangeWithMultipleAnnotationsAtClassLevel() throws NoSuchMethodException {
RequestMappingHandlerMapping mapping = createMapping();
Class<?> controllerClass = MultipleClassLevelAnnotationsHttpExchangeController.class;
Method method = controllerClass.getDeclaredMethod("post");
assertThatIllegalStateException()
.isThrownBy(() -> mapping.getMappingForMethod(method, controllerClass))
.withMessageContainingAll(
"Multiple @HttpExchange annotations found on " + controllerClass,
"@" + HttpExchange.class.getName(),
"@" + ExtraHttpExchange.class.getName()
);
}
@Test // gh-32049
void httpExchangeWithMultipleAnnotationsAtMethodLevel() throws NoSuchMethodException {
RequestMappingHandlerMapping mapping = createMapping();
Class<?> controllerClass = MultipleMethodLevelAnnotationsHttpExchangeController.class;
Method method = controllerClass.getDeclaredMethod("post");
assertThatIllegalStateException()
.isThrownBy(() -> mapping.getMappingForMethod(method, controllerClass))
.withMessageContainingAll(
"Multiple @HttpExchange annotations found on " + method,
"@" + PostExchange.class.getName(),
"@" + PutExchange.class.getName()
);
}
@SuppressWarnings("DataFlowIssue")
@Test
void httpExchangeWithDefaultValues() throws NoSuchMethodException {
@@ -437,6 +471,30 @@ class RequestMappingHandlerMappingTests {
}
@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 {
}
private static class Foo {
}