Rossen Stoyanchev
2017-10-20 16:41:40 -04:00
parent 8ad212dae2
commit 1cc5afe24b
197 changed files with 1688 additions and 994 deletions

View File

@@ -84,7 +84,9 @@ public abstract class BodyExtractors {
* @param <T> the element type
* @return a {@code BodyExtractor} that reads a mono
*/
public static <T> BodyExtractor<Mono<T>, ReactiveHttpInputMessage> toMono(ParameterizedTypeReference<T> typeReference) {
public static <T> BodyExtractor<Mono<T>, ReactiveHttpInputMessage> toMono(
ParameterizedTypeReference<T> typeReference) {
Assert.notNull(typeReference, "'typeReference' must not be null");
return toMono(ResolvableType.forType(typeReference.getType()));
}
@@ -134,7 +136,9 @@ public abstract class BodyExtractors {
* @param <T> the element type
* @return a {@code BodyExtractor} that reads a flux
*/
public static <T> BodyExtractor<Flux<T>, ReactiveHttpInputMessage> toFlux(ParameterizedTypeReference<T> typeReference) {
public static <T> BodyExtractor<Flux<T>, ReactiveHttpInputMessage> toFlux(
ParameterizedTypeReference<T> typeReference) {
Assert.notNull(typeReference, "'typeReference' must not be null");
return toFlux(ResolvableType.forType(typeReference.getType()));
}
@@ -174,12 +178,13 @@ public abstract class BodyExtractors {
// ReactiveHttpInputMessage like other methods, since reading form data only typically happens on
// the server-side
public static BodyExtractor<Mono<MultiValueMap<String, String>>, ServerHttpRequest> toFormData() {
return (serverRequest, context) -> {
HttpMessageReader<MultiValueMap<String, String>> messageReader =
messageReader(FORM_MAP_TYPE, MediaType.APPLICATION_FORM_URLENCODED, context);
return (request, context) -> {
ResolvableType type = FORM_MAP_TYPE;
HttpMessageReader<MultiValueMap<String, String>> reader =
messageReader(type, MediaType.APPLICATION_FORM_URLENCODED, context);
return context.serverResponse()
.map(serverResponse -> messageReader.readMono(FORM_MAP_TYPE, FORM_MAP_TYPE, serverRequest, serverResponse, context.hints()))
.orElseGet(() -> messageReader.readMono(FORM_MAP_TYPE, serverRequest, context.hints()));
.map(response -> reader.readMono(type, type, request, response, context.hints()))
.orElseGet(() -> reader.readMono(type, request, context.hints()));
};
}
@@ -193,12 +198,12 @@ public abstract class BodyExtractors {
// the server-side
public static BodyExtractor<Mono<MultiValueMap<String, Part>>, ServerHttpRequest> toMultipartData() {
return (serverRequest, context) -> {
HttpMessageReader<MultiValueMap<String, Part>> messageReader =
messageReader(MULTIPART_MAP_TYPE, MediaType.MULTIPART_FORM_DATA, context);
ResolvableType type = MULTIPART_MAP_TYPE;
HttpMessageReader<MultiValueMap<String, Part>> reader =
messageReader(type, MediaType.MULTIPART_FORM_DATA, context);
return context.serverResponse()
.map(serverResponse -> messageReader.readMono(MULTIPART_MAP_TYPE,
MULTIPART_MAP_TYPE, serverRequest, serverResponse, context.hints()))
.orElseGet(() -> messageReader.readMono(MULTIPART_MAP_TYPE, serverRequest, context.hints()));
.map(response -> reader.readMono(type, type, serverRequest, response, context.hints()))
.orElseGet(() -> reader.readMono(type, serverRequest, context.hints()));
};
}
@@ -212,11 +217,11 @@ public abstract class BodyExtractors {
// the server-side
public static BodyExtractor<Flux<Part>, ServerHttpRequest> toParts() {
return (serverRequest, context) -> {
HttpMessageReader<Part> messageReader =
messageReader(PART_TYPE, MediaType.MULTIPART_FORM_DATA, context);
ResolvableType type = PART_TYPE;
HttpMessageReader<Part> reader = messageReader(type, MediaType.MULTIPART_FORM_DATA, context);
return context.serverResponse()
.map(serverResponse -> messageReader.read(PART_TYPE, PART_TYPE, serverRequest, serverResponse, context.hints()))
.orElseGet(() -> messageReader.read(PART_TYPE, serverRequest, context.hints()));
.map(response -> reader.read(type, type, serverRequest, response, context.hints()))
.orElseGet(() -> reader.read(type, serverRequest, context.hints()));
};
}

View File

@@ -298,7 +298,9 @@ class DefaultWebClient implements WebClient {
}
@Override
public <T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, ParameterizedTypeReference<T> typeReference) {
public <T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher,
ParameterizedTypeReference<T> typeReference) {
this.inserter = BodyInserters.fromPublisher(publisher, typeReference);
return this;
}

View File

@@ -42,10 +42,11 @@ import org.springframework.util.Assert;
public abstract class ExchangeFilterFunctions {
/**
* Name of the {@link ClientRequest} attribute that contains the {@link Credentials}, as used by
* {@link #basicAuthentication()}
* Name of the {@link ClientRequest} attribute that contains the
* {@link Credentials}, as used by {@link #basicAuthentication()}.
*/
public static final String BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE = ExchangeFilterFunctions.class.getName() + ".basicAuthenticationCredentials";
public static final String BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE =
ExchangeFilterFunctions.class.getName() + ".basicAuthenticationCredentials";
/**

View File

@@ -86,7 +86,9 @@ public interface EntityResponse<T> extends ServerResponse {
* @param <P> the type of the {@code Publisher}
* @return the created builder
*/
static <T, P extends Publisher<T>> Builder<P> fromPublisher(P publisher, ParameterizedTypeReference<T> typeReference) {
static <T, P extends Publisher<T>> Builder<P> fromPublisher(P publisher,
ParameterizedTypeReference<T> typeReference) {
return new DefaultEntityResponseBuilder<>(publisher,
BodyInserters.fromPublisher(publisher, typeReference));
}

View File

@@ -71,8 +71,9 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
private final RequestConditionHolder customConditionHolder;
public RequestMappingInfo(@Nullable String name, @Nullable PatternsRequestCondition patterns, @Nullable RequestMethodsRequestCondition methods,
@Nullable ParamsRequestCondition params, @Nullable HeadersRequestCondition headers, @Nullable ConsumesRequestCondition consumes,
public RequestMappingInfo(@Nullable String name, @Nullable PatternsRequestCondition patterns,
@Nullable RequestMethodsRequestCondition methods, @Nullable ParamsRequestCondition params,
@Nullable HeadersRequestCondition headers, @Nullable ConsumesRequestCondition consumes,
@Nullable ProducesRequestCondition produces, @Nullable RequestCondition<?> custom) {
this.name = (StringUtils.hasText(name) ? name : null);
@@ -88,8 +89,9 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
/**
* Creates a new instance with the given request conditions.
*/
public RequestMappingInfo(@Nullable PatternsRequestCondition patterns, @Nullable RequestMethodsRequestCondition methods,
@Nullable ParamsRequestCondition params, @Nullable HeadersRequestCondition headers, @Nullable ConsumesRequestCondition consumes,
public RequestMappingInfo(@Nullable PatternsRequestCondition patterns,
@Nullable RequestMethodsRequestCondition methods, @Nullable ParamsRequestCondition params,
@Nullable HeadersRequestCondition headers, @Nullable ConsumesRequestCondition consumes,
@Nullable ProducesRequestCondition produces, @Nullable RequestCondition<?> custom) {
this(null, patterns, methods, params, headers, consumes, produces, custom);

View File

@@ -75,7 +75,9 @@ public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodAr
* values are not expected to contain expressions
* @param registry for checking reactive type wrappers
*/
public AbstractNamedValueArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public AbstractNamedValueArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(registry);
this.configurableBeanFactory = factory;
this.expressionContext = (factory != null ? new BeanExpressionContext(factory, null) : null);

View File

@@ -44,7 +44,9 @@ public class CookieValueMethodArgumentResolver extends AbstractNamedValueSyncArg
* or {@code null} if default values are not expected to contain expressions
* @param registry for checking reactive type wrappers
*/
public CookieValueMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public CookieValueMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(factory, registry);
}

View File

@@ -42,7 +42,9 @@ public class ExpressionValueMethodArgumentResolver extends AbstractNamedValueSyn
* or {@code null} if default values are not expected to contain expressions
* @param registry for checking reactive type wrappers
*/
public ExpressionValueMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public ExpressionValueMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(factory, registry);
}

View File

@@ -60,7 +60,9 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueSyncAr
* or {@code null} if default values are not expected to contain expressions
* @param registry for checking reactive type wrappers
*/
public PathVariableMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public PathVariableMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(factory, registry);
}

View File

@@ -42,7 +42,9 @@ public class RequestAttributeMethodArgumentResolver extends AbstractNamedValueSy
* or {@code null} if default values are not expected to have expressions
* @param registry for checking reactive type wrappers
*/
public RequestAttributeMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public RequestAttributeMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(factory, registry);
}

View File

@@ -53,7 +53,9 @@ public class RequestHeaderMethodArgumentResolver extends AbstractNamedValueSyncA
* or {@code null} if default values are not expected to have expressions
* @param registry for checking reactive type wrappers
*/
public RequestHeaderMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory, ReactiveAdapterRegistry registry) {
public RequestHeaderMethodArgumentResolver(@Nullable ConfigurableBeanFactory factory,
ReactiveAdapterRegistry registry) {
super(factory, registry);
}

View File

@@ -113,7 +113,9 @@ public class HttpMessageWriterView implements View {
@Override
@SuppressWarnings("unchecked")
public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, ServerWebExchange exchange) {
public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType,
ServerWebExchange exchange) {
Object value = getObjectToRender(model);
return (value != null) ?
write(value, contentType, exchange) :

View File

@@ -84,11 +84,9 @@ public class DelegatingWebFluxConfigurationTests {
@Test
public void requestMappingHandlerAdapter() throws Exception {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
RequestMappingHandlerAdapter adapter = delegatingConfig.requestMappingHandlerAdapter();
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
ConversionService initializerConversionService = initializer.getConversionService();
assertTrue(initializer.getValidator() instanceof LocalValidatorFactoryBean);
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)
this.delegatingConfig.requestMappingHandlerAdapter().getWebBindingInitializer();
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
verify(webFluxConfigurer).getValidator();
@@ -96,7 +94,9 @@ public class DelegatingWebFluxConfigurationTests {
verify(webFluxConfigurer).addFormatters(formatterRegistry.capture());
verify(webFluxConfigurer).configureArgumentResolvers(any());
assertSame(formatterRegistry.getValue(), initializerConversionService);
assertNotNull(initializer);
assertTrue(initializer.getValidator() instanceof LocalValidatorFactoryBean);
assertSame(formatterRegistry.getValue(), initializer.getConversionService());
assertEquals(12, codecsConfigurer.getValue().getReaders().size());
}

View File

@@ -87,8 +87,8 @@ public class WebFluxConfigurationSupportTests {
@Test
public void requestMappingHandlerMapping() throws Exception {
ApplicationContext context = loadConfig(WebFluxConfig.class);
final Field trailingSlashField = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
ReflectionUtils.makeAccessible(trailingSlashField);
final Field field = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
ReflectionUtils.makeAccessible(field);
String name = "requestMappingHandlerMapping";
RequestMappingHandlerMapping mapping = context.getBean(name, RequestMappingHandlerMapping.class);
@@ -96,9 +96,9 @@ public class WebFluxConfigurationSupportTests {
assertEquals(0, mapping.getOrder());
assertNotNull(mapping.getPathPatternParser());
boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils
.getField(trailingSlashField, mapping.getPathPatternParser());
PathPatternParser patternParser = mapping.getPathPatternParser();
assertNotNull(patternParser);
boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils.getField(field, patternParser);
assertTrue(matchOptionalTrailingSlash);
name = "webFluxContentTypeResolver";
@@ -112,16 +112,16 @@ public class WebFluxConfigurationSupportTests {
@Test
public void customPathMatchConfig() throws Exception {
ApplicationContext context = loadConfig(CustomPatchMatchConfig.class);
final Field trailingSlashField = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
ReflectionUtils.makeAccessible(trailingSlashField);
final Field field = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
ReflectionUtils.makeAccessible(field);
String name = "requestMappingHandlerMapping";
RequestMappingHandlerMapping mapping = context.getBean(name, RequestMappingHandlerMapping.class);
assertNotNull(mapping);
assertNotNull(mapping.getPathPatternParser());
boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils
.getField(trailingSlashField, mapping.getPathPatternParser());
PathPatternParser patternParser = mapping.getPathPatternParser();
assertNotNull(patternParser);
boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils.getField(field, patternParser);
assertFalse(matchOptionalTrailingSlash);
}
@@ -136,11 +136,13 @@ public class WebFluxConfigurationSupportTests {
List<HttpMessageReader<?>> readers = adapter.getMessageReaders();
assertEquals(12, readers.size());
ResolvableType multiValueMapType = forClassWithGenerics(MultiValueMap.class, String.class, String.class);
assertHasMessageReader(readers, forClass(byte[].class), APPLICATION_OCTET_STREAM);
assertHasMessageReader(readers, forClass(ByteBuffer.class), APPLICATION_OCTET_STREAM);
assertHasMessageReader(readers, forClass(String.class), TEXT_PLAIN);
assertHasMessageReader(readers, forClass(Resource.class), IMAGE_PNG);
assertHasMessageReader(readers, forClassWithGenerics(MultiValueMap.class, String.class, String.class), APPLICATION_FORM_URLENCODED);
assertHasMessageReader(readers, multiValueMapType, APPLICATION_FORM_URLENCODED);
assertHasMessageReader(readers, forClass(TestBean.class), APPLICATION_XML);
assertHasMessageReader(readers, forClass(TestBean.class), APPLICATION_JSON);
assertHasMessageReader(readers, forClass(TestBean.class), new MediaType("application", "x-jackson-smile"));

View File

@@ -126,8 +126,8 @@ public class BodyExtractorsTests {
@Test
public void toMonoParameterizedTypeReference() throws Exception {
ParameterizedTypeReference<Map<String, String>> typeReference = new ParameterizedTypeReference<Map<String, String>>() {};
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(typeReference);
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor =
BodyExtractors.toMono(new ParameterizedTypeReference<Map<String, String>>() {});
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
DefaultDataBuffer dataBuffer =
@@ -206,8 +206,8 @@ public class BodyExtractorsTests {
this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class);
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
DefaultDataBuffer dataBuffer =
factory.wrap(ByteBuffer.wrap("[{\"username\":\"foo\",\"password\":\"bar\"},{\"username\":\"bar\",\"password\":\"baz\"}]".getBytes(StandardCharsets.UTF_8)));
String text = "[{\"username\":\"foo\",\"password\":\"bar\"},{\"username\":\"bar\",\"password\":\"baz\"}]";
DefaultDataBuffer dataBuffer = factory.wrap(ByteBuffer.wrap(text.getBytes(StandardCharsets.UTF_8)));
Flux<DataBuffer> body = Flux.just(dataBuffer);
MockServerHttpRequest request = MockServerHttpRequest.post("/")
@@ -270,8 +270,8 @@ public class BodyExtractorsTests {
BodyExtractor<Mono<MultiValueMap<String, String>>, ServerHttpRequest> extractor = BodyExtractors.toFormData();
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
DefaultDataBuffer dataBuffer =
factory.wrap(ByteBuffer.wrap("name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes(StandardCharsets.UTF_8)));
String text = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3";
DefaultDataBuffer dataBuffer = factory.wrap(ByteBuffer.wrap(text.getBytes(StandardCharsets.UTF_8)));
Flux<DataBuffer> body = Flux.just(dataBuffer);
MockServerHttpRequest request = MockServerHttpRequest.post("/")

View File

@@ -66,7 +66,8 @@ public class PathResourceLookupFunctionTests {
.uri(new URI("http://localhost/resources/child/response.txt"))
.build();
Mono<Resource> result = function.apply(request);
File expected = new ClassPathResource("org/springframework/web/reactive/function/server/child/response.txt").getFile();
String path = "org/springframework/web/reactive/function/server/child/response.txt";
File expected = new ClassPathResource(path).getFile();
StepVerifier.create(result)
.expectNextMatches(resource -> {
try {

View File

@@ -41,7 +41,7 @@ public class ProducesRequestConditionTests {
@Test
public void match() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/plain");
assertNotNull(condition.getMatchingCondition(exchange));
@@ -49,7 +49,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchNegated() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition = new ProducesRequestCondition("!text/plain");
assertNull(condition.getMatchingCondition(exchange));
@@ -63,7 +63,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchWildcard() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/*");
assertNotNull(condition.getMatchingCondition(exchange));
@@ -71,7 +71,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchMultiple() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/plain", "application/xml");
assertNotNull(condition.getMatchingCondition(exchange));
@@ -79,7 +79,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchSingle() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "application/xml"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "application/xml"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/plain");
assertNull(condition.getMatchingCondition(exchange));
@@ -87,7 +87,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchParseError() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "bogus"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "bogus"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/plain");
assertNull(condition.getMatchingCondition(exchange));
@@ -95,7 +95,7 @@ public class ProducesRequestConditionTests {
@Test
public void matchParseErrorWithNegation() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "bogus"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "bogus"));
ProducesRequestCondition condition = new ProducesRequestCondition("!text/plain");
assertNull(condition.getMatchingCondition(exchange));
@@ -107,7 +107,7 @@ public class ProducesRequestConditionTests {
ProducesRequestCondition xml = new ProducesRequestCondition("application/xml");
ProducesRequestCondition none = new ProducesRequestCondition();
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "application/xml, text/html"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "application/xml, text/html"));
assertTrue(html.compareTo(xml, exchange) > 0);
assertTrue(xml.compareTo(html, exchange) < 0);
@@ -117,20 +117,20 @@ public class ProducesRequestConditionTests {
assertTrue(none.compareTo(html, exchange) > 0);
exchange = MockServerWebExchange.from(
MockServerHttpRequest.get("/").header("Accept", "application/xml, text/*"));
get("/").header("Accept", "application/xml, text/*"));
assertTrue(html.compareTo(xml, exchange) > 0);
assertTrue(xml.compareTo(html, exchange) < 0);
exchange = MockServerWebExchange.from(
MockServerHttpRequest.get("/").header("Accept", "application/pdf"));
get("/").header("Accept", "application/pdf"));
assertTrue(html.compareTo(xml, exchange) == 0);
assertTrue(xml.compareTo(html, exchange) == 0);
// See SPR-7000
exchange = MockServerWebExchange.from(
MockServerHttpRequest.get("/").header("Accept", "text/html;q=0.9,application/xml"));
get("/").header("Accept", "text/html;q=0.9,application/xml"));
assertTrue(html.compareTo(xml, exchange) > 0);
assertTrue(xml.compareTo(html, exchange) < 0);
@@ -138,7 +138,7 @@ public class ProducesRequestConditionTests {
@Test
public void compareToWithSingleExpression() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition1 = new ProducesRequestCondition("text/plain");
ProducesRequestCondition condition2 = new ProducesRequestCondition("text/*");
@@ -155,7 +155,7 @@ public class ProducesRequestConditionTests {
ProducesRequestCondition condition1 = new ProducesRequestCondition("*/*", "text/plain");
ProducesRequestCondition condition2 = new ProducesRequestCondition("text/*", "text/plain;q=0.7");
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
int result = condition1.compareTo(condition2, exchange);
assertTrue("Invalid comparison result: " + result, result < 0);
@@ -179,7 +179,7 @@ public class ProducesRequestConditionTests {
assertTrue("Invalid comparison result: " + result, result > 0);
exchange = MockServerWebExchange.from(
MockServerHttpRequest.get("/").header("Accept", "application/xml", "text/plain"));
get("/").header("Accept", "application/xml", "text/plain"));
result = condition1.compareTo(condition2, exchange);
assertTrue("Invalid comparison result: " + result, result > 0);
@@ -192,7 +192,7 @@ public class ProducesRequestConditionTests {
@Test
public void compareToMediaTypeAll() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/"));
ProducesRequestCondition condition1 = new ProducesRequestCondition();
ProducesRequestCondition condition2 = new ProducesRequestCondition("application/json");
@@ -209,7 +209,7 @@ public class ProducesRequestConditionTests {
assertTrue(condition2.compareTo(condition1, exchange) > 0);
exchange = MockServerWebExchange.from(
MockServerHttpRequest.get("/").header("Accept", "*/*"));
get("/").header("Accept", "*/*"));
condition1 = new ProducesRequestCondition();
condition2 = new ProducesRequestCondition("application/json");
@@ -228,7 +228,7 @@ public class ProducesRequestConditionTests {
@Test
public void compareToMediaTypeAllWithParameter() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "*/*;q=0.9"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "*/*;q=0.9"));
ProducesRequestCondition condition1 = new ProducesRequestCondition();
ProducesRequestCondition condition2 = new ProducesRequestCondition("application/json");
@@ -239,7 +239,7 @@ public class ProducesRequestConditionTests {
@Test
public void compareToEqualMatch() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/*"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/*"));
ProducesRequestCondition condition1 = new ProducesRequestCondition("text/plain");
ProducesRequestCondition condition2 = new ProducesRequestCondition("text/xhtml");
@@ -280,7 +280,7 @@ public class ProducesRequestConditionTests {
@Test
public void getMatchingCondition() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/").header("Accept", "text/plain"));
MockServerWebExchange exchange = MockServerWebExchange.from(get("/").header("Accept", "text/plain"));
ProducesRequestCondition condition = new ProducesRequestCondition("text/plain", "application/xml");

View File

@@ -18,9 +18,11 @@ package org.springframework.web.reactive.result.method;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
@@ -190,9 +192,12 @@ public class RequestMappingInfoHandlerMappingTests {
@Test
public void getHandlerHttpOptions() throws Exception {
List<HttpMethod> allMethodExceptTrace = new ArrayList<>(Arrays.asList(HttpMethod.values()));
allMethodExceptTrace.remove(HttpMethod.TRACE);
testHttpOptions("/foo", EnumSet.of(HttpMethod.GET, HttpMethod.HEAD));
testHttpOptions("/person/1", EnumSet.of(HttpMethod.PUT));
testHttpOptions("/persons", EnumSet.of(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH, HttpMethod.DELETE, HttpMethod.OPTIONS));
testHttpOptions("/persons", EnumSet.copyOf(allMethodExceptTrace));
testHttpOptions("/something", EnumSet.of(HttpMethod.PUT, HttpMethod.POST));
}

View File

@@ -85,9 +85,12 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat
@Test
public void jsonViewWithFluxRequest() throws Exception {
String expected = "[{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}," +
String expected = "[" +
"{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}," +
"{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}]";
List<JacksonViewBean> beans = Arrays.asList(new JacksonViewBean("with", "with", "without"), new JacksonViewBean("with", "with", "without"));
List<JacksonViewBean> beans = Arrays.asList(
new JacksonViewBean("with", "with", "without"),
new JacksonViewBean("with", "with", "without"));
assertEquals(expected, performPost("/request/flux", MediaType.APPLICATION_JSON, beans,
MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
}

View File

@@ -321,7 +321,7 @@ public class MessageReaderArgumentResolverTests {
return false;
}
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext, ServerWebExchange exchange) {
public Mono<Object> resolveArgument(MethodParameter p, BindingContext bc, ServerWebExchange e) {
return null;
}
};

View File

@@ -67,7 +67,8 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq
@Test
public void controllerThrowingExceptionWithCauseToHandle() throws Exception {
String expected = "Recovered from error: IO";
assertEquals(expected, performGet("/thrown-exception-with-cause-to-handle", new HttpHeaders(), String.class).getBody());
String url = "/thrown-exception-with-cause-to-handle";
assertEquals(expected, performGet(url, new HttpHeaders(), String.class).getBody());
}
@Test

View File

@@ -360,7 +360,8 @@ public class RequestMappingMessageConversionIntegrationTests extends AbstractReq
@Test
public void personCreateWithRxJava2ObservableXml() throws Exception {
People people = new People(new Person("Robert"), new Person("Marie"));
ResponseEntity<Void> response = performPost("/person-create/rxjava2-observable", APPLICATION_XML, people, null, Void.class);
String url = "/person-create/rxjava2-observable";
ResponseEntity<Void> response = performPost(url, APPLICATION_XML, people, null, Void.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(2, getApplicationContext().getBean(PersonCreateController.class).persons.size());
@@ -600,7 +601,9 @@ public class RequestMappingMessageConversionIntegrationTests extends AbstractReq
}
@PostMapping("/rxjava2-observable")
public io.reactivex.Completable createWithRxJava2Observable(@RequestBody io.reactivex.Observable<Person> observable) {
public io.reactivex.Completable createWithRxJava2Observable(
@RequestBody io.reactivex.Observable<Person> observable) {
return observable.toList().doOnSuccess(persons::addAll).toCompletable();
}

View File

@@ -235,7 +235,8 @@ public class ResponseEntityResultHandlerTests {
public void handleReturnValueLastModified() throws Exception {
Instant currentTime = Instant.now().truncatedTo(ChronoUnit.SECONDS);
Instant oneMinAgo = currentTime.minusSeconds(60);
MockServerWebExchange exchange = MockServerWebExchange.from(get("/path").ifModifiedSince(currentTime.toEpochMilli()));
long timestamp = currentTime.toEpochMilli();
MockServerWebExchange exchange = MockServerWebExchange.from(get("/path").ifModifiedSince(timestamp));
ResponseEntity<String> entity = ok().lastModified(oneMinAgo.toEpochMilli()).body("body");
MethodParameter returnType = on(TestController.class).resolveReturnType(entity(String.class));

View File

@@ -68,11 +68,12 @@ public class AbstractViewTests {
TestView view = new TestView();
StepVerifier.create(view.render(attributes, null, this.exchange)).verifyComplete();
assertEquals(testBean1, view.attributes.get("attr1"));
assertArrayEquals(new TestBean[] {testBean1, testBean2}, ((List<TestBean>)view.attributes.get("attr2")).toArray());
assertEquals(testBean2, view.attributes.get("attr3"));
assertArrayEquals(new TestBean[] {testBean1, testBean2}, ((List<TestBean>)view.attributes.get("attr4")).toArray());
assertNull(view.attributes.get("attr5"));
Map<String, Object> actual = view.attributes;
assertEquals(testBean1, actual.get("attr1"));
assertArrayEquals(new TestBean[] {testBean1, testBean2}, ((List<TestBean>) actual.get("attr2")).toArray());
assertEquals(testBean2, actual.get("attr3"));
assertArrayEquals(new TestBean[] {testBean1, testBean2}, ((List<TestBean>) actual.get("attr4")).toArray());
assertNull(actual.get("attr5"));
}
@@ -81,7 +82,9 @@ public class AbstractViewTests {
private Map<String, Object> attributes;
@Override
protected Mono<Void> renderInternal(Map<String, Object> renderAttributes, MediaType contentType, ServerWebExchange exchange) {
protected Mono<Void> renderInternal(Map<String, Object> renderAttributes,
MediaType contentType, ServerWebExchange exchange) {
this.attributes = renderAttributes;
return Mono.empty();
}

View File

@@ -45,7 +45,8 @@ public class JRubyScriptTemplateTests {
Map<String, Object> model = new HashMap<>();
model.put("title", "Layout example");
model.put("body", "This is the body");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/jruby/template.erb", model);
String url = "org/springframework/web/reactive/result/view/script/jruby/template.erb";
MockServerHttpResponse response = renderViewWithModel(url, model);
assertEquals("<html><head><title>Layout example</title></head><body><p>This is the body</p></body></html>",
response.getBodyAsString().block());
}

View File

@@ -43,7 +43,8 @@ public class JythonScriptTemplateTests {
Map<String, Object> model = new HashMap<>();
model.put("title", "Layout example");
model.put("body", "This is the body");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/jython/template.html", model);
String url = "org/springframework/web/reactive/result/view/script/jython/template.html";
MockServerHttpResponse response = renderViewWithModel(url, model);
assertEquals("<html><head><title>Layout example</title></head><body><p>This is the body</p></body></html>",
response.getBodyAsString().block());
}

View File

@@ -46,20 +46,18 @@ public class KotlinScriptTemplateTests {
public void renderTemplateWithFrenchLocale() throws Exception {
Map<String, Object> model = new HashMap<>();
model.put("foo", "Foo");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/kotlin/template.kts",
model, Locale.FRENCH, ScriptTemplatingConfiguration.class);
assertEquals("<html><body>\n<p>Bonjour Foo</p>\n</body></html>",
response.getBodyAsString().block());
String url = "org/springframework/web/reactive/result/view/script/kotlin/template.kts";
MockServerHttpResponse response = render(url, model, Locale.FRENCH, ScriptTemplatingConfiguration.class);
assertEquals("<html><body>\n<p>Bonjour Foo</p>\n</body></html>", response.getBodyAsString().block());
}
@Test
public void renderTemplateWithEnglishLocale() throws Exception {
Map<String, Object> model = new HashMap<>();
model.put("foo", "Foo");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/kotlin/template.kts",
model, Locale.ENGLISH, ScriptTemplatingConfiguration.class);
assertEquals("<html><body>\n<p>Hello Foo</p>\n</body></html>",
response.getBodyAsString().block());
String url = "org/springframework/web/reactive/result/view/script/kotlin/template.kts";
MockServerHttpResponse response = render(url, model, Locale.ENGLISH, ScriptTemplatingConfiguration.class);
assertEquals("<html><body>\n<p>Hello Foo</p>\n</body></html>", response.getBodyAsString().block());
}
@Test
@@ -69,14 +67,15 @@ public class KotlinScriptTemplateTests {
model.put("hello", "Hello");
model.put("foo", "Foo");
model.put("footer", "</body></html>");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/kotlin/eval.kts",
model, Locale.ENGLISH, ScriptTemplatingConfigurationWithoutRenderFunction.class);
String url = "org/springframework/web/reactive/result/view/script/kotlin/eval.kts";
Class<?> configClass = ScriptTemplatingConfigurationWithoutRenderFunction.class;
MockServerHttpResponse response = render(url, model, Locale.ENGLISH, configClass);
assertEquals("<html><body>\n<p>Hello Foo</p>\n</body></html>",
response.getBodyAsString().block());
}
private MockServerHttpResponse renderViewWithModel(String viewUrl, Map<String, Object> model,
private MockServerHttpResponse render(String viewUrl, Map<String, Object> model,
Locale locale, Class<?> configuration) throws Exception {
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);

View File

@@ -43,21 +43,24 @@ public class NashornScriptTemplateTests {
Map<String, Object> model = new HashMap<>();
model.put("title", "Layout example");
model.put("body", "This is the body");
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/nashorn/template.html",
model, ScriptTemplatingConfiguration.class);
String url = "org/springframework/web/reactive/result/view/script/nashorn/template.html";
MockServerHttpResponse response = render(url, model, ScriptTemplatingConfiguration.class);
assertEquals("<html><head><title>Layout example</title></head><body><p>This is the body</p></body></html>",
response.getBodyAsString().block());
}
@Test // SPR-13453
public void renderTemplateWithUrl() throws Exception {
MockServerHttpResponse response = renderViewWithModel("org/springframework/web/reactive/result/view/script/nashorn/template.html",
null, ScriptTemplatingWithUrlConfiguration.class);
assertEquals("<html><head><title>Check url parameter</title></head><body><p>org/springframework/web/reactive/result/view/script/nashorn/template.html</p></body></html>",
String url = "org/springframework/web/reactive/result/view/script/nashorn/template.html";
Class<?> configClass = ScriptTemplatingWithUrlConfiguration.class;
MockServerHttpResponse response = render(url, null, configClass);
assertEquals("<html><head><title>Check url parameter</title></head><body><p>" + url + "</p></body></html>",
response.getBodyAsString().block());
}
private MockServerHttpResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Class<?> configuration) throws Exception {
private MockServerHttpResponse render(String viewUrl, Map<String, Object> model,
Class<?> configuration) throws Exception {
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
view.renderInternal(model, MediaType.TEXT_HTML, exchange).block();

View File

@@ -1,7 +1,8 @@
import javax.script.*
import org.springframework.web.reactive.result.view.script.RenderingContext
import org.springframework.context.support.ResourceBundleMessageSource
import org.springframework.beans.factory.getBean
import org.springframework.context.support.ResourceBundleMessageSource
import org.springframework.web.reactive.result.view.script.RenderingContext
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
fun render(template: String, model: Map<String, Any>, renderingContext: RenderingContext): String {
val engine = ScriptEngineManager().getEngineByName("kotlin")