From 452106f287a604025b1dbf3c1825647ef29b7cd0 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 20 Jan 2017 13:10:54 +0000 Subject: [PATCH] Fix some logic with media types If user sends "Accept: */*" we don't want to default to sending an SSE (for instance). So the logic for detecting those preferences has to take MediaType.ALL into account as a special case. --- .../web/flux/FluxReturnValueHandler.java | 2 +- .../flux/ResponseBodyEmitterSubscriber.java | 6 +-- .../function/web/RestApplicationTests.java | 37 ++++++++++++++++++- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FluxReturnValueHandler.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FluxReturnValueHandler.java index f469f0d96..59c4b2396 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FluxReturnValueHandler.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FluxReturnValueHandler.java @@ -84,7 +84,7 @@ public class FluxReturnValueHandler implements AsyncHandlerMethodReturnValueHand } private ResponseBodyEmitter getEmitter(Long timeout, Flux flux, MediaType mediaType) { - if (EVENT_STREAM.isCompatibleWith(mediaType)) { + if (!MediaType.ALL.equals(mediaType) && EVENT_STREAM.isCompatibleWith(mediaType)) { return new FluxResponseSseEmitter<>(timeout, mediaType, flux); } return new FluxResponseBodyEmitter<>(timeout, mediaType, flux); diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ResponseBodyEmitterSubscriber.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ResponseBodyEmitterSubscriber.java index f06130039..98dfdbc79 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ResponseBodyEmitterSubscriber.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ResponseBodyEmitterSubscriber.java @@ -56,7 +56,7 @@ class ResponseBodyEmitterSubscriber implements Subscriber, Runnable { @Override public void onSubscribe(Subscription subscription) { - if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { + if (!MediaType.ALL.equals(mediaType) && MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { try { this.responseBodyEmitter.send("["); } @@ -74,7 +74,7 @@ class ResponseBodyEmitterSubscriber implements Subscriber, Runnable { Object object = value; try { - if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { + if (!MediaType.ALL.equals(mediaType) && MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { if (!this.firstElementWritten) { this.firstElementWritten = true; } @@ -106,7 +106,7 @@ class ResponseBodyEmitterSubscriber implements Subscriber, Runnable { if (!completed) { completed = true; try { - if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { + if (!MediaType.ALL.equals(mediaType) && MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { if (!this.firstElementWritten) { this.firstElementWritten = true; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/RestApplicationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/RestApplicationTests.java index 34475a1d0..2fe637ab1 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/RestApplicationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/RestApplicationTests.java @@ -16,7 +16,9 @@ package org.springframework.cloud.function.web; import java.net.URI; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; @@ -77,6 +79,32 @@ public class RestApplicationTests { String.class).getBody()).isEqualTo("foobar"); } + @Test + public void sentences() throws Exception { + assertThat(rest.exchange(RequestEntity + .get(new URI("http://localhost:" + port + "/sentences")).build(), + String.class).getBody()) + .isEqualTo("[\"go\",\"home\"][\"come\",\"back\"]"); + } + + @Test + public void sentencesAcceptAny() throws Exception { + assertThat(rest.exchange( + RequestEntity.get(new URI("http://localhost:" + port + "/sentences")) + .accept(MediaType.ALL).build(), + String.class).getBody()) + .isEqualTo("[\"go\",\"home\"][\"come\",\"back\"]"); + } + + @Test + public void sentencesAcceptSse() throws Exception { + assertThat(rest.exchange( + RequestEntity.get(new URI("http://localhost:" + port + "/sentences")) + .accept(EVENT_STREAM).build(), + String.class).getBody()) + .isEqualTo(sse("[\"go\",\"home\"]","[\"come\",\"back\"]")); + } + @Test public void uppercase() { assertThat(rest.postForObject("http://localhost:" + port + "/uppercase", @@ -123,7 +151,8 @@ public class RestApplicationTests { @Bean public Function, Flux> uppercase() { - return flux -> flux.log().map(value -> "[" + value.trim().toUpperCase() + "]"); + return flux -> flux.log() + .map(value -> "[" + value.trim().toUpperCase() + "]"); } @Bean @@ -139,6 +168,12 @@ public class RestApplicationTests { return () -> Flux.fromArray(new String[] { "foo", "bar" }); } + @Bean + public Supplier>> sentences() { + return () -> Flux.just(Arrays.asList("go", "home"), + Arrays.asList("come", "back")); + } + } }