Add support for single valued Supplier as well

This commit is contained in:
Dave Syer
2017-05-24 10:29:47 +01:00
parent 20a6796793
commit 5589804d2c
4 changed files with 49 additions and 24 deletions

View File

@@ -20,6 +20,8 @@ import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;
@@ -137,9 +139,8 @@ public class FluxReturnValueHandler implements AsyncHandlerMethodReturnValueHand
NativeWebRequest.SCOPE_REQUEST);
Class<?> type = inspector.getOutputType(inspector.getName(handler));
Boolean inputSingle = (Boolean) webRequest.getAttribute(
WebRequestConstants.INPUT_SINGLE, NativeWebRequest.SCOPE_REQUEST);
if (inputSingle!=null && inputSingle && isOutputSingle(handler)) {
boolean inputSingle = isInputSingle(webRequest, handler);
if (inputSingle && isOutputSingle(handler)) {
single.handleReturnValue(Flux.from(flux).blockFirst(), singleReturnType,
mavContainer, webRequest);
return;
@@ -160,11 +161,23 @@ public class FluxReturnValueHandler implements AsyncHandlerMethodReturnValueHand
mavContainer, webRequest);
}
private boolean isInputSingle(NativeWebRequest webRequest, Object handler) {
Boolean single = (Boolean) webRequest.getAttribute(
WebRequestConstants.INPUT_SINGLE, NativeWebRequest.SCOPE_REQUEST);
if (single == null) {
return handler instanceof Supplier;
}
return single;
}
private boolean isOutputSingle(Object handler) {
String name = inspector.getName(handler);
Class<?> type = inspector.getOutputType(name);
Class<?> wrapper = inspector.getOutputWrapper(name);
if (wrapper==type) {
if (Stream.class.isAssignableFrom(type)) {
return false;
}
if (wrapper == type) {
return true;
}
if (Mono.class.equals(wrapper) || Optional.class.equals(wrapper)) {

View File

@@ -109,6 +109,14 @@ public class RestApplicationTests {
assertThat(result.getBody()).isEqualTo("[\"foo\",\"bar\"]");
}
@Test
public void word() throws Exception {
ResponseEntity<String> result = rest
.exchange(RequestEntity.get(new URI("/word")).build(), String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isEqualTo("foo");
}
@Test
public void foos() throws Exception {
ResponseEntity<String> result = rest
@@ -120,9 +128,9 @@ public class RestApplicationTests {
@Test
public void qualifierFoos() throws Exception {
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/foos")).contentType(MediaType.APPLICATION_JSON)
.body("[\"foo\",\"bar\"]"), String.class);
ResponseEntity<String> result = rest.exchange(RequestEntity.post(new URI("/foos"))
.contentType(MediaType.APPLICATION_JSON).body("[\"foo\",\"bar\"]"),
String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody())
.isEqualTo("[{\"value\":\"[FOO]\"},{\"value\":\"[BAR]\"}]");
@@ -249,18 +257,21 @@ public class RestApplicationTests {
@Test
public void uppercaseSingleValue() throws Exception {
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/uppercase")).contentType(MediaType.TEXT_PLAIN)
.body("foo"), String.class);
ResponseEntity<String> result = rest
.exchange(
RequestEntity.post(new URI("/uppercase"))
.contentType(MediaType.TEXT_PLAIN).body("foo"),
String.class);
assertThat(result.getBody()).isEqualTo("(FOO)");
}
@Test
@Ignore("WebFlux would split the request body into lines: TODO make this work the same")
public void uppercasePlainText() throws Exception {
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/uppercase")).contentType(MediaType.TEXT_PLAIN)
.body("foo\nbar"), String.class);
ResponseEntity<String> result = rest.exchange(
RequestEntity.post(new URI("/uppercase"))
.contentType(MediaType.TEXT_PLAIN).body("foo\nbar"),
String.class);
assertThat(result.getBody()).isEqualTo("(FOO)(BAR)");
}
@@ -279,8 +290,7 @@ public class RestApplicationTests {
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/upFoos")).contentType(MediaType.APPLICATION_JSON)
.body("{\"value\":\"foo\"}"), String.class);
assertThat(result.getBody())
.isEqualTo("[{\"value\":\"FOO\"}]");
assertThat(result.getBody()).isEqualTo("[{\"value\":\"FOO\"}]");
}
@Test
@@ -294,12 +304,12 @@ public class RestApplicationTests {
@Test
public void bareUppercaseFoo() throws Exception {
// Single Foo can be parsed and returns a single value if the function is defined that way
// Single Foo can be parsed and returns a single value if the function is defined
// that way
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/bareUpFoos")).contentType(MediaType.APPLICATION_JSON)
.body("{\"value\":\"foo\"}"), String.class);
assertThat(result.getBody())
.isEqualTo("{\"value\":\"FOO\"}");
assertThat(result.getBody()).isEqualTo("{\"value\":\"FOO\"}");
}
@Test
@@ -430,6 +440,11 @@ public class RestApplicationTests {
return () -> Flux.just("foo", "bar");
}
@Bean
public Supplier<String> word() {
return () -> "foo";
}
@Bean
public Supplier<Flux<Foo>> foos() {
return () -> Flux.just(new Foo("foo"), new Foo("bar"));