GH-228 Added support for treating text/* CT as a special case
Resolves #228
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user