Add support for headers in @HttpExchange

On the client side, supports `name=value` pairs. Placeholders in values
are resolved by the `embeddedValueResolver`.
On the server side, additionally supports `name` and `!name` syntax.

Closes gh-33309
This commit is contained in:
Simon Baslé
2024-08-09 12:46:02 +02:00
parent b61eee7fb0
commit bf5e218b35
14 changed files with 181 additions and 6 deletions

View File

@@ -296,7 +296,8 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
.paths(resolveEmbeddedValuesInPatterns(toStringArray(httpExchange.value())))
.methods(toMethodArray(httpExchange.method()))
.consumes(toStringArray(httpExchange.contentType()))
.produces(httpExchange.accept());
.produces(httpExchange.accept())
.headers(httpExchange.headers());
if (customCondition != null) {
builder.customCondition(customCondition);

View File

@@ -303,6 +303,26 @@ class RequestMappingHandlerMappingTests {
.containsOnly(MediaType.valueOf("text/plain;charset=UTF-8"));
}
@SuppressWarnings("DataFlowIssue")
@Test
void httpExchangeWithCustomHeaders() {
this.handlerMapping.afterPropertiesSet();
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
mapping.setApplicationContext(new StaticWebApplicationContext());
mapping.afterPropertiesSet();
Class<HttpExchangeController> clazz = HttpExchangeController.class;
Method method = ReflectionUtils.findMethod(clazz, "customHeadersExchange");
RequestMappingInfo mappingInfo = mapping.getMappingForMethod(method, clazz);
assertThat(mappingInfo.getMethodsCondition().getMethods()).containsOnly(RequestMethod.GET);
assertThat(mappingInfo.getParamsCondition().getExpressions()).isEmpty();
assertThat(mappingInfo.getHeadersCondition().getExpressions().stream().map(Object::toString))
.containsExactly("h1=hv1", "!h2");
}
private RequestMappingInfo assertComposedAnnotationMapping(RequestMethod requestMethod) {
String methodName = requestMethod.name().toLowerCase();
String path = "/" + methodName;
@@ -409,6 +429,12 @@ class RequestMappingHandlerMappingTests {
@PostExchange(url = "/custom", contentType = "application/json", accept = "text/plain;charset=UTF-8")
public void customValuesExchange(){}
@HttpExchange(method="GET", url = "/headers",
headers = {"h1=hv1", "!h2", "Accept=application/ignored"})
public String customHeadersExchange() {
return "info";
}
}
@HttpExchange("/exchange")