GH-228 Added support for treating text/* CT as a special case

Resolves #228
This commit is contained in:
Oleg Zhurakousky
2018-11-16 12:46:58 +01:00
parent e9b289d995
commit c46f25a000
5 changed files with 69 additions and 35 deletions

View File

@@ -123,38 +123,34 @@ public class RequestProcessor {
.flatMap(body -> response(wrapper, body, false));
}
public Mono<ResponseEntity<?>> post(FunctionWrapper wrapper, String body,
boolean stream) {
public Mono<ResponseEntity<?>> post(FunctionWrapper wrapper, String body, boolean stream) {
Object function = wrapper.handler();
Class<?> inputType = inspector.getInputType(function);
Type itemType = getItemType(function);
Object input = body;
if (StringUtils.hasText(body) && this.mapper != null) {
if (body.startsWith("[")) {
Class<?> collectionType = Collection.class.isAssignableFrom(inputType)
? inputType
: Collection.class;
if (StringUtils.hasText(body)) {
MediaType contentType = wrapper.headers.getContentType();
if (contentType != null && "text".equalsIgnoreCase(contentType.getType())) {
input = converter.convert(function, body);
}
else if (body.startsWith("[")) {
Class<?> collectionType = Collection.class.isAssignableFrom(inputType) ? inputType : Collection.class;
input = mapper.toObject(body,
ResolvableType
.forClassWithGenerics(collectionType, (Class<?>) itemType)
.getType());
ResolvableType.forClassWithGenerics(collectionType, (Class<?>) itemType).getType());
}
else if (body.startsWith("{")) {
input = mapper.toObject(body, inputType);
}
else if (body.startsWith("\"")) {
input = body.substring(1, body.length() - 2);
}
else {
if (inputType == String.class) {
input = body;
}
else if (body.startsWith("{")) {
input = mapper.toObject(body, inputType);
}
else if (body.startsWith("\"")) {
input = body.substring(1, body.length() - 2);
}
else {
input = converter.convert(function, body);
}
input = converter.convert(function, body);
}
}
return response(wrapper, input, stream);
}

View File

@@ -50,6 +50,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
@@ -93,7 +94,7 @@ public class HttpPostIntegrationTests {
@Test
public void updates() throws Exception {
ResponseEntity<String> result = rest.exchange(
RequestEntity.post(new URI("/updates")).body("[\"one\", \"two\"]"),
RequestEntity.post(new URI("/updates")).contentType(MediaType.APPLICATION_JSON).body("[\"one\", \"two\"]"),
String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);
assertThat(test.list).hasSize(2);
@@ -205,6 +206,15 @@ public class HttpPostIntegrationTests {
.isEqualTo("[{\"value\":\"FOO\"},{\"value\":\"BAR\"}]");
}
@Test
public void typelessFunctionPassingArray() throws Exception {
ResponseEntity<String> result = rest.exchange(RequestEntity
.post(new URI("/typelessFunctionExpectingText")).contentType(MediaType.TEXT_PLAIN)
.body("[{\"value\":\"foo\"}]"), String.class);
assertThat(result.getBody())
.isEqualTo("[{\"value\":\"foo\"}]");
}
@Test
public void bareUppercaseFoo() throws Exception {
// Single Foo can be parsed and returns a single value if the function is defined
@@ -375,6 +385,20 @@ public class HttpPostIntegrationTests {
return value -> new Foo(value.getValue().trim().toUpperCase());
}
@Bean
public Function<?, ?> typelessFunctionExpectingText() {
return value -> {
Assert.isInstanceOf(String.class, value);
return value;
};
}
// @Bean
// public Function<byte[],?> byteArrayInputFunction() {
//// return value -> new Foo(value.getValue().trim().toUpperCase());
// throw new UnsupportedOperationException("boom?");
// }
@Bean
public Function<Flux<Integer>, Flux<String>> wrap() {
return flux -> flux.log().map(value -> ".." + value + "..");
@@ -396,7 +420,9 @@ public class HttpPostIntegrationTests {
@Bean
@Qualifier("foos")
public Function<String, Foo> qualifier() {
return value -> new Foo("[" + value.trim().toUpperCase() + "]");
return value -> {
return new Foo("[" + value.trim().toUpperCase() + "]");
};
}
@Bean

View File

@@ -32,8 +32,8 @@ import org.springframework.cloud.function.web.RestApplication;
import org.springframework.cloud.function.web.mvc.HeadersToMessageTests.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.ContextConfiguration;
@@ -59,9 +59,9 @@ public class HeadersToMessageTests {
@Test
public void testBodyAndCustomHeaderFromMessagePropagation() throws Exception {
ResponseEntity<String> postForEntity = rest.postForEntity(
new URI("/functions/employee"), "{\"name\":\"Bob\",\"age\":25}",
String.class);
HttpEntity<String> postForEntity = rest.exchange(RequestEntity
.post(new URI("/functions/employee")).contentType(MediaType.APPLICATION_JSON)
.body("{\"name\":\"Bob\",\"age\":25}"), String.class);
assertEquals("{\"name\":\"Bob\",\"age\":25}", postForEntity.getBody());
assertTrue(postForEntity.getHeaders().containsKey("x-content-type"));
assertEquals("application/xml",
@@ -72,7 +72,7 @@ public class HeadersToMessageTests {
@Test
public void testHeadersPropagatedByDefault() throws Exception {
HttpEntity<String> postForEntity = rest.exchange(RequestEntity
.post(new URI("/functions/vanilla")).header("x-context-type", "rubbish")
.post(new URI("/functions/vanilla")).contentType(MediaType.APPLICATION_JSON).header("x-context-type", "rubbish")
.body("{\"name\":\"Bob\",\"age\":25}"), String.class);
assertEquals("{\"name\":\"Bob\",\"age\":25,\"foo\":\"bar\"}",
postForEntity.getBody());

View File

@@ -92,7 +92,7 @@ public class HttpPostIntegrationTests {
@Test
public void updates() throws Exception {
ResponseEntity<String> result = rest.exchange(
RequestEntity.post(new URI("/updates")).body("[\"one\", \"two\"]"),
RequestEntity.post(new URI("/updates")).contentType(MediaType.APPLICATION_JSON).body("[\"one\", \"two\"]"),
String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);
assertThat(test.list).hasSize(2);