Empty body checks in ConsumesRequestCondition
Normally consumes matches the "Content-Type" header but what should be done if there is no content? This commit adds checks for method parameters with @RequestBody(required=false) and if "false" then also match requests with no content. Closes gh-22010
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -99,6 +99,24 @@ public class ConsumesRequestConditionTests {
|
||||
assertNull(condition.getMatchingCondition(exchange));
|
||||
}
|
||||
|
||||
@Test // gh-22010
|
||||
public void consumesNoContent() {
|
||||
ConsumesRequestCondition condition = new ConsumesRequestCondition("text/plain");
|
||||
condition.setBodyRequired(false);
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/").build();
|
||||
assertNotNull(condition.getMatchingCondition(MockServerWebExchange.from(request)));
|
||||
|
||||
request = MockServerHttpRequest.get("/").header(HttpHeaders.CONTENT_LENGTH, "0").build();
|
||||
assertNotNull(condition.getMatchingCondition(MockServerWebExchange.from(request)));
|
||||
|
||||
request = MockServerHttpRequest.get("/").header(HttpHeaders.CONTENT_LENGTH, "21").build();
|
||||
assertNull(condition.getMatchingCondition(MockServerWebExchange.from(request)));
|
||||
|
||||
request = MockServerHttpRequest.get("/").header(HttpHeaders.TRANSFER_ENCODING, "chunked").build();
|
||||
assertNull(condition.getMatchingCondition(MockServerWebExchange.from(request)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareToSingle() throws Exception {
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -32,16 +31,20 @@ import org.junit.Test;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerTypePredicate;
|
||||
import org.springframework.web.reactive.result.condition.ConsumesRequestCondition;
|
||||
import org.springframework.web.reactive.result.condition.PatternsRequestCondition;
|
||||
import org.springframework.web.reactive.result.method.RequestMappingInfo;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
@@ -103,10 +106,26 @@ public class RequestMappingHandlerMappingTests {
|
||||
|
||||
@Test // SPR-14988
|
||||
public void getMappingOverridesConsumesFromTypeLevelAnnotation() throws Exception {
|
||||
RequestMappingInfo requestMappingInfo = assertComposedAnnotationMapping(RequestMethod.GET);
|
||||
RequestMappingInfo requestMappingInfo = assertComposedAnnotationMapping(RequestMethod.POST);
|
||||
|
||||
assertArrayEquals(new MediaType[]{MediaType.ALL}, new ArrayList<>(
|
||||
requestMappingInfo.getConsumesCondition().getConsumableMediaTypes()).toArray());
|
||||
ConsumesRequestCondition condition = requestMappingInfo.getConsumesCondition();
|
||||
assertEquals(Collections.singleton(MediaType.APPLICATION_XML), condition.getConsumableMediaTypes());
|
||||
}
|
||||
|
||||
@Test // gh-22010
|
||||
public void consumesWithOptionalRequestBody() {
|
||||
this.wac.registerSingleton("testController", ComposedAnnotationController.class);
|
||||
this.wac.refresh();
|
||||
this.handlerMapping.afterPropertiesSet();
|
||||
RequestMappingInfo info = this.handlerMapping.getHandlerMethods().keySet().stream()
|
||||
.filter(i -> {
|
||||
PatternsRequestCondition condition = i.getPatternsCondition();
|
||||
return condition.getPatterns().iterator().next().getPatternString().equals("/post");
|
||||
})
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("No /post"));
|
||||
|
||||
assertFalse(info.getConsumesCondition().isBodyRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,7 +165,7 @@ public class RequestMappingHandlerMappingTests {
|
||||
RequestMethod requestMethod) throws Exception {
|
||||
|
||||
Class<?> clazz = ComposedAnnotationController.class;
|
||||
Method method = clazz.getMethod(methodName);
|
||||
Method method = ClassUtils.getMethod(clazz, methodName, null);
|
||||
RequestMappingInfo info = this.handlerMapping.getMappingForMethod(method, clazz);
|
||||
|
||||
assertNotNull(info);
|
||||
@@ -175,12 +194,12 @@ public class RequestMappingHandlerMappingTests {
|
||||
public void postJson() {
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get", consumes = MediaType.ALL_VALUE)
|
||||
@GetMapping("/get")
|
||||
public void get() {
|
||||
}
|
||||
|
||||
@PostMapping("/post")
|
||||
public void post() {
|
||||
@PostMapping(path = "/post", consumes = MediaType.APPLICATION_XML_VALUE)
|
||||
public void post(@RequestBody(required = false) Foo foo) {
|
||||
}
|
||||
|
||||
@PutMapping("/put")
|
||||
@@ -196,6 +215,9 @@ public class RequestMappingHandlerMappingTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Foo {
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE,
|
||||
|
||||
Reference in New Issue
Block a user