diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java index 2c61a9da3e..19d5b804d9 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java @@ -16,7 +16,6 @@ package org.springframework.core; -import java.util.Optional; import java.util.function.Function; import org.reactivestreams.Publisher; @@ -106,7 +105,6 @@ public class ReactiveAdapter { */ @SuppressWarnings("unchecked") public Publisher toPublisher(Object source) { - source = (source instanceof Optional ? ((Optional) source).orElse(null) : source); if (source == null) { source = getDescriptor().getEmptyValue(); } diff --git a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java index 0fa0868019..e956c438fc 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.mock.http.server.reactive; import java.net.InetSocketAddress; @@ -22,7 +23,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; -import java.util.Optional; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -89,8 +89,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.ofNullable(this.remoteAddress); + public InetSocketAddress getRemoteAddress() { + return this.remoteAddress; } @Override diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultControllerSpec.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultControllerSpec.java index 47a196fbe2..b9c0cba3bf 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultControllerSpec.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultControllerSpec.java @@ -19,7 +19,6 @@ package org.springframework.test.web.reactive.server; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.function.Consumer; import org.springframework.context.ApplicationContext; @@ -199,8 +198,8 @@ class DefaultControllerSpec extends AbstractMockServerSpec getValidator() { - return Optional.ofNullable(this.validator); + public Validator getValidator() { + return this.validator; } @Override diff --git a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java index decc77a0cf..1a8f37798c 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java @@ -17,13 +17,12 @@ package org.springframework.http; import java.time.Duration; -import java.util.Optional; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * An {@code HttpCookie} sub-class with the additional attributes allowed in + * An {@code HttpCookie} subclass with the additional attributes allowed in * the "Set-Cookie" response header. To build an instance use the {@link #from} * static method. * @@ -35,9 +34,9 @@ public final class ResponseCookie extends HttpCookie { private final Duration maxAge; - private final Optional domain; + private final String domain; - private final Optional path; + private final String path; private final boolean secure; @@ -53,8 +52,8 @@ public final class ResponseCookie extends HttpCookie { super(name, value); Assert.notNull(maxAge, "Max age must not be null"); this.maxAge = maxAge; - this.domain = Optional.ofNullable(domain); - this.path = Optional.ofNullable(path); + this.domain = domain; + this.path = path; this.secure = secure; this.httpOnly = httpOnly; } @@ -72,16 +71,16 @@ public final class ResponseCookie extends HttpCookie { } /** - * Return the cookie "Domain" attribute. + * Return the cookie "Domain" attribute, or {@code null} if not set. */ - public Optional getDomain() { + public String getDomain() { return this.domain; } /** - * Return the cookie "Path" attribute. + * Return the cookie "Path" attribute, or {@code null} if not set. */ - public Optional getPath() { + public String getPath() { return this.path; } diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEvent.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEvent.java index 122ef0097d..da9f4a1738 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEvent.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,21 +17,21 @@ package org.springframework.http.codec; import java.time.Duration; -import java.util.Optional; import org.springframework.http.codec.json.Jackson2JsonEncoder; /** - * Representation for a Server-Sent Event for use with Spring's reactive Web - * support. {@code Flux} or {@code Observable} is the + * Representation for a Server-Sent Event for use with Spring's reactive Web support. + * {@code Flux} or {@code Observable} is the * reactive equivalent to Spring MVC's {@code SseEmitter}. * * @param the type of data that this event contains + * * @author Sebastien Deleuze * @author Arjen Poutsma + * @since 5.0 * @see ServerSentEventHttpMessageWriter * @see Server-Sent Events W3C recommendation - * @since 5.0 */ public class ServerSentEvent { @@ -54,68 +54,69 @@ public class ServerSentEvent { this.comment = comment; } - /** - * Return a builder for a {@code SseEvent}. - * - * @param the type of data that this event contains - * @return the builder - */ - public static Builder builder() { - return new BuilderImpl<>(); - } - - /** - * Return a builder for a {@code SseEvent}, populated with the give {@linkplain #data() data}. - * - * @param the type of data that this event contains - * @return the builder - */ - public static Builder builder(T data) { - return new BuilderImpl<>(data); - } /** * Return the {@code id} field of this event, if available. */ - public Optional id() { - return Optional.ofNullable(this.id); + public String id() { + return this.id; } /** * Return the {@code event} field of this event, if available. */ - public Optional event() { - return Optional.ofNullable(this.event); + public String event() { + return this.event; } /** * Return the {@code data} field of this event, if available. */ - public Optional data() { - return Optional.ofNullable(this.data); + public T data() { + return this.data; } /** * Return the {@code retry} field of this event, if available. */ - public Optional retry() { - return Optional.ofNullable(this.retry); + public Duration retry() { + return this.retry; } /** * Return the comment of this event, if available. */ - public Optional comment() { - return Optional.ofNullable(this.comment); + public String comment() { + return this.comment; } + @Override public String toString() { - return "ServerSentEvent [id = '" + id + '\'' + ", event='" + event + '\'' + - ", data=" + data + ", retry=" + retry + ", comment='" + comment + '\'' + - ']'; + return ("ServerSentEvent [id = '" + this.id + '\'' + ", event='" + this.event + '\'' + + ", data=" + this.data + ", retry=" + this.retry + ", comment='" + this.comment + '\'' + ']'); } + + /** + * Return a builder for a {@code SseEvent}. + * @param the type of data that this event contains + * @return the builder + */ + public static Builder builder() { + return new BuilderImpl<>(); + } + + /** + * Return a builder for a {@code SseEvent}, populated with the give {@linkplain #data() data}. + * @param the type of data that this event contains + * @return the builder + */ + public static Builder builder(T data) { + return new BuilderImpl<>(data); + } + + /** * A mutable builder for a {@code SseEvent}. * diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java index 86313aca4a..a6859ccc98 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,8 +62,9 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter encoder) { this.encoder = encoder; @@ -71,7 +72,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter getEncoder() { return this.encoder; @@ -85,8 +86,8 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter> encode(Publisher input, DataBufferFactory factory, ResolvableType elementType, Map hints) { - ResolvableType valueType = ServerSentEvent.class.isAssignableFrom(elementType.getRawClass()) ? - elementType.getGeneric(0) : elementType; + ResolvableType valueType = (ServerSentEvent.class.isAssignableFrom(elementType.getRawClass()) ? + elementType.getGeneric() : elementType); return Flux.from(input).map(element -> { - ServerSentEvent sse = element instanceof ServerSentEvent ? - (ServerSentEvent) element : ServerSentEvent.builder().data(element).build(); + ServerSentEvent sse = (element instanceof ServerSentEvent ? + (ServerSentEvent) element : ServerSentEvent.builder().data(element).build()); StringBuilder sb = new StringBuilder(); - sse.id().ifPresent(v -> writeField("id", v, sb)); - sse.event().ifPresent(v -> writeField("event", v, sb)); - sse.retry().ifPresent(v -> writeField("retry", v.toMillis(), sb)); - sse.comment().ifPresent(v -> sb.append(':').append(v.replaceAll("\\n", "\n:")).append("\n")); - sse.data().ifPresent(v -> sb.append("data:")); + if (sse.id() != null) { + writeField("id", sse.id(), sb); + } + if (sse.event() != null) { + writeField("event", sse.event(), sb); + } + if (sse.retry() != null) { + writeField("retry", sse.retry().toMillis(), sb); + } + if (sse.comment() != null) { + sb.append(':').append(sse.comment().replaceAll("\\n", "\n:")).append("\n"); + } + if (sse.data() != null) { + sb.append("data:"); + } return Flux.concat(encodeText(sb, factory), - encodeData(sse, valueType, factory, hints), + encodeData(sse.data(), valueType, factory, hints), encodeText("\n", factory)); }); } @@ -129,10 +140,9 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter Flux encodeData(ServerSentEvent event, ResolvableType valueType, + private Flux encodeData(T data, ResolvableType valueType, DataBufferFactory factory, Map hints) { - Object data = event.data().orElse(null); if (data == null) { return Flux.empty(); } @@ -147,7 +157,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter) this.encoder) - .encode(Mono.just((T) data), factory, valueType, MediaType.TEXT_EVENT_STREAM, hints) + .encode(Mono.just(data), factory, valueType, MediaType.TEXT_EVENT_STREAM, hints) .concatWith(encodeText("\n", factory)); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java index 3692b9de38..c2dad3f156 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java @@ -19,7 +19,6 @@ package org.springframework.http.server.reactive; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; -import java.util.Optional; import io.netty.handler.codec.http.cookie.Cookie; import reactor.core.publisher.Flux; @@ -100,8 +99,8 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.ofNullable(this.request.remoteAddress()); + public InetSocketAddress getRemoteAddress() { + return this.request.remoteAddress(); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java index 36a95cb689..a733e276f6 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java @@ -42,15 +42,14 @@ import org.springframework.util.Assert; * @author Rossen Stoyanchev * @since 5.0 */ -public class ReactorServerHttpResponse extends AbstractServerHttpResponse - implements ZeroCopyHttpOutputMessage { +public class ReactorServerHttpResponse extends AbstractServerHttpResponse implements ZeroCopyHttpOutputMessage { private final HttpServerResponse response; public ReactorServerHttpResponse(HttpServerResponse response, DataBufferFactory bufferFactory) { super(bufferFactory); - Assert.notNull(response, "'response' must not be null."); + Assert.notNull(response, "HttpServerResponse must not be null"); this.response = response; } @@ -98,8 +97,12 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse if (!httpCookie.getMaxAge().isNegative()) { cookie.setMaxAge(httpCookie.getMaxAge().getSeconds()); } - httpCookie.getDomain().ifPresent(cookie::setDomain); - httpCookie.getPath().ifPresent(cookie::setPath); + if (httpCookie.getDomain() != null) { + cookie.setDomain(httpCookie.getDomain()); + } + if (httpCookie.getPath() != null) { + cookie.setPath(httpCookie.getPath()); + } cookie.setSecure(httpCookie.isSecure()); cookie.setHttpOnly(httpCookie.isHttpOnly()); this.response.addCookie(cookie); @@ -116,6 +119,4 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse return Flux.from(dataBuffers).map(NettyDataBufferFactory::toByteBuf); } - - } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java index 1710f60d50..dac0090f5e 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.http.server.reactive; import java.net.InetSocketAddress; -import java.util.Optional; import org.springframework.http.HttpCookie; import org.springframework.http.HttpMethod; @@ -35,11 +34,10 @@ import org.springframework.util.MultiValueMap; public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage { /** - * Returns the portion of the URL path that represents the context path for - * the current {@link HttpHandler}. The context path is always at the - * beginning of the request path. It starts with "/" but but does not end - * with "/". This method may return an empty string if no context path is - * configured. + * Returns the portion of the URL path that represents the context path for the + * current {@link HttpHandler}. The context path is always at the beginning of + * the request path. It starts with "/" but but does not end with "/". + *

This method may return an empty string if no context path is configured. * @return the context path (not decoded) or an empty string */ default String getContextPath() { @@ -57,10 +55,9 @@ public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage MultiValueMap getCookies(); /** - * Returns the remote address where this request is connected to. - * @return remote address if available + * Return the remote address where this request is connected to, if available. */ - Optional getRemoteAddress(); + InetSocketAddress getRemoteAddress(); /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java index 38a42cba98..9eae180525 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server.reactive; import java.net.InetSocketAddress; import java.net.URI; -import java.util.Optional; import reactor.core.publisher.Flux; @@ -79,7 +79,7 @@ public class ServerHttpRequestDecorator implements ServerHttpRequest { } @Override - public Optional getRemoteAddress() { + public InetSocketAddress getRemoteAddress() { return getDelegate().getRemoteAddress(); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index 95eed9cef3..eafbbbfb96 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.Map; -import java.util.Optional; import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; @@ -32,10 +31,10 @@ import javax.servlet.ServletInputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; -import reactor.core.publisher.Flux; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; + import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.HttpCookie; @@ -178,9 +177,8 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.of(new InetSocketAddress( - this.request.getRemoteHost(), this.request.getRemotePort())); + public InetSocketAddress getRemoteAddress() { + return new InetSocketAddress(this.request.getRemoteHost(), this.request.getRemotePort()); } @Override @@ -231,13 +229,12 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest { } } + private class RequestBodyPublisher extends AbstractListenerReadPublisher { private final ServletInputStream inputStream; - public RequestBodyPublisher(ServletInputStream inputStream) { - this.inputStream = inputStream; } @@ -260,6 +257,7 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest { return null; } + private class RequestBodyPublisherReadListener implements ReadListener { @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index 21503168eb..3f101c270a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -117,8 +117,12 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons if (!httpCookie.getMaxAge().isNegative()) { cookie.setMaxAge((int) httpCookie.getMaxAge().getSeconds()); } - httpCookie.getDomain().ifPresent(cookie::setDomain); - httpCookie.getPath().ifPresent(cookie::setPath); + if (httpCookie.getDomain() != null) { + cookie.setDomain(httpCookie.getDomain()); + } + if (httpCookie.getPath() != null) { + cookie.setPath(httpCookie.getPath()); + } cookie.setSecure(httpCookie.isSecure()); cookie.setHttpOnly(httpCookie.isHttpOnly()); this.response.addCookie(cookie); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java index adbd69e80e..98eb90d4ec 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.URI; import java.nio.ByteBuffer; -import java.util.Optional; import io.undertow.connector.ByteBufferPool; import io.undertow.connector.PooledByteBuffer; @@ -100,8 +99,8 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.ofNullable(this.exchange.getSourceAddress()); + public InetSocketAddress getRemoteAddress() { + return this.exchange.getSourceAddress(); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java index bc8728e159..a9029f5ce1 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java @@ -60,7 +60,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon public UndertowServerHttpResponse(HttpServerExchange exchange, DataBufferFactory bufferFactory) { super(bufferFactory); - Assert.notNull(exchange, "HttpServerExchange is required"); + Assert.notNull(exchange, "HttpServerExchange must not be null"); this.exchange = exchange; } @@ -120,8 +120,12 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon if (!httpCookie.getMaxAge().isNegative()) { cookie.setMaxAge((int) httpCookie.getMaxAge().getSeconds()); } - httpCookie.getDomain().ifPresent(cookie::setDomain); - httpCookie.getPath().ifPresent(cookie::setPath); + if (httpCookie.getDomain() != null) { + cookie.setDomain(httpCookie.getDomain()); + } + if (httpCookie.getPath() != null) { + cookie.setPath(httpCookie.getPath()); + } cookie.setSecure(httpCookie.isSecure()); cookie.setHttpOnly(httpCookie.isHttpOnly()); this.exchange.getResponseCookies().putIfAbsent(name, cookie); diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java index df57e6b7f1..10a6ef615e 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -263,9 +263,8 @@ public class WebExchangeBindException extends ServerWebInputException implements * Returns diagnostic information about the errors held in this object. */ @Override - @SuppressWarnings("OptionalGetWithoutIsPresent") public String getMessage() { - MethodParameter parameter = getMethodParameter().get(); + MethodParameter parameter = getMethodParameter(); StringBuilder sb = new StringBuilder("Validation failed for argument at index ") .append(parameter.getParameterIndex()).append(" in method: ") .append(parameter.getMethod().toGenericString()) diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java b/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java index 03ab79b9df..513a67fbbf 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.web.server; -import java.util.Optional; - import org.springframework.core.MethodParameter; import org.springframework.http.HttpStatus; @@ -61,8 +59,8 @@ public class ServerErrorException extends ResponseStatusException { /** * Return the {@code MethodParameter} associated with this error, if any. */ - public Optional getMethodParameter() { - return Optional.ofNullable(this.parameter); + public MethodParameter getMethodParameter() { + return this.parameter; } } diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java index 5f03e02858..874c79f684 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java @@ -126,12 +126,10 @@ public interface ServerWebExchange { * status, and adding "ETag" and "Last-Modified" headers when applicable. * This method works with conditional GET/HEAD requests as well as with * conditional POST/PUT/DELETE requests. - * *

Note: The HTTP specification recommends setting both * ETag and Last-Modified values, but you can also use * {@code #checkNotModified(String)} or * {@link #checkNotModified(Instant)}. - * * @param etag the entity tag that the application determined for the * underlying resource. This parameter will be padded with quotes (") * if necessary. diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebInputException.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebInputException.java index ada54e5fc0..91f60f4304 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebInputException.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebInputException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.web.server; -import java.util.Optional; - import org.springframework.core.MethodParameter; import org.springframework.http.HttpStatus; @@ -61,8 +59,8 @@ public class ServerWebInputException extends ResponseStatusException { /** * Return the {@code MethodParameter} associated with this error, if any. */ - public Optional getMethodParameter() { - return Optional.ofNullable(this.parameter); + public MethodParameter getMethodParameter() { + return this.parameter; } } diff --git a/spring-web/src/main/java/org/springframework/web/server/UnsupportedMediaTypeStatusException.java b/spring-web/src/main/java/org/springframework/web/server/UnsupportedMediaTypeStatusException.java index 713c7f8916..308951a297 100644 --- a/spring-web/src/main/java/org/springframework/web/server/UnsupportedMediaTypeStatusException.java +++ b/spring-web/src/main/java/org/springframework/web/server/UnsupportedMediaTypeStatusException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.web.server; import java.util.Collections; import java.util.List; -import java.util.Optional; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -57,10 +56,11 @@ public class UnsupportedMediaTypeStatusException extends ResponseStatusException /** - * Return the request Content-Type header if it was parsed successfully. + * Return the request Content-Type header if it was parsed successfully, + * or {@code null} otherwise. */ - public Optional getContentType() { - return Optional.ofNullable(this.contentType); + public MediaType getContentType() { + return this.contentType; } /** diff --git a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java index 11182584be..0b7f2987f3 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageReaderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,7 @@ import org.springframework.http.MediaType; import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author Sebastien Deleuze @@ -41,6 +39,7 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll private ServerSentEventHttpMessageReader messageReader = new ServerSentEventHttpMessageReader(new Jackson2JsonDecoder()); + @Test public void cantRead() { assertFalse(messageReader.canRead(ResolvableType.forClass(Object.class), @@ -58,7 +57,6 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll @Test public void readServerSentEvents() { - MockServerHttpRequest request = MockServerHttpRequest.post("/").body( "id:c42\nevent:foo\nretry:123\n:bla\n:bla bla\n:bla bla bla\ndata:bar\n\n" + "id:c43\nevent:bar\nretry:456\ndata:baz\n\n"); @@ -69,18 +67,18 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll StepVerifier.create(events) .consumeNextWith(event -> { - assertEquals("c42", event.id().get()); - assertEquals("foo", event.event().get()); - assertEquals(Duration.ofMillis(123), event.retry().get()); - assertEquals("bla\nbla bla\nbla bla bla", event.comment().get()); - assertEquals("bar", event.data().get()); + assertEquals("c42", event.id()); + assertEquals("foo", event.event()); + assertEquals(Duration.ofMillis(123), event.retry()); + assertEquals("bla\nbla bla\nbla bla bla", event.comment()); + assertEquals("bar", event.data()); }) .consumeNextWith(event -> { - assertEquals("c43", event.id().get()); - assertEquals("bar", event.event().get()); - assertEquals(Duration.ofMillis(456), event.retry().get()); - assertFalse(event.comment().isPresent()); - assertEquals("baz", event.data().get()); + assertEquals("c43", event.id()); + assertEquals("bar", event.event()); + assertEquals(Duration.ofMillis(456), event.retry()); + assertNull(event.comment()); + assertEquals("baz", event.data()); }) .expectComplete() .verify(); @@ -88,7 +86,6 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll @Test public void readServerSentEventsWithMultipleChunks() { - MockServerHttpRequest request = MockServerHttpRequest.post("/") .body(Flux.just( stringBuffer("id:c42\nev"), @@ -101,18 +98,18 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll StepVerifier.create(events) .consumeNextWith(event -> { - assertEquals("c42", event.id().get()); - assertEquals("foo", event.event().get()); - assertEquals(Duration.ofMillis(123), event.retry().get()); - assertEquals("bla\nbla bla\nbla bla bla", event.comment().get()); - assertEquals("bar", event.data().get()); + assertEquals("c42", event.id()); + assertEquals("foo", event.event()); + assertEquals(Duration.ofMillis(123), event.retry()); + assertEquals("bla\nbla bla\nbla bla bla", event.comment()); + assertEquals("bar", event.data()); }) .consumeNextWith(event -> { - assertEquals("c43", event.id().get()); - assertEquals("bar", event.event().get()); - assertEquals(Duration.ofMillis(456), event.retry().get()); - assertFalse(event.comment().isPresent()); - assertEquals("baz", event.data().get()); + assertEquals("c43", event.id()); + assertEquals("bar", event.event()); + assertEquals(Duration.ofMillis(456), event.retry()); + assertNull(event.comment()); + assertEquals("baz", event.data()); }) .expectComplete() .verify(); @@ -120,7 +117,6 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll @Test public void readString() { - String body = "data:foo\ndata:bar\n\ndata:baz\n\n"; MockServerHttpRequest request = MockServerHttpRequest.post("/").body(body); @@ -136,7 +132,6 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll @Test public void readPojo() { - MockServerHttpRequest request = MockServerHttpRequest.post("/").body( "data:{\"foo\": \"foofoo\", \"bar\": \"barbar\"}\n\n" + "data:{\"foo\": \"foofoofoo\", \"bar\": \"barbarbar\"}\n\n"); @@ -157,9 +152,8 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll .verify(); } - @Test // SPR-15331 + @Test // SPR-15331 public void decodeFullContentAsString() { - String body = "data:foo\ndata:bar\n\ndata:baz\n\n"; MockServerHttpRequest request = MockServerHttpRequest.post("/").body(body); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpRequest.java b/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpRequest.java index 05918cdae7..d10e0004d1 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpRequest.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpRequest.java @@ -19,7 +19,6 @@ package org.springframework.http.server.reactive; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; -import java.util.Optional; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.cookie.Cookie; @@ -59,19 +58,20 @@ public class RxNettyServerHttpRequest extends AbstractServerHttpRequest { throws URISyntaxException { super(initUri(request, remoteAddress), initHeaders(request)); - - Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null"); this.request = request; + + Assert.notNull(dataBufferFactory, "NettyDataBufferFactory must not be null"); this.dataBufferFactory = dataBufferFactory; + this.remoteAddress = remoteAddress; } private static URI initUri(HttpServerRequest request, InetSocketAddress remoteAddress) throws URISyntaxException { - Assert.notNull(request, "'request' must not be null"); + Assert.notNull(request, "HttpServerRequest must not be null"); String requestUri = request.getUri(); - return remoteAddress != null ? createUrl(remoteAddress, requestUri) : URI.create(requestUri); + return (remoteAddress != null ? createUrl(remoteAddress, requestUri) : URI.create(requestUri)); } private static URI createUrl(InetSocketAddress address, String requestUri) throws URISyntaxException { @@ -110,8 +110,8 @@ public class RxNettyServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.ofNullable(this.remoteAddress); + public InetSocketAddress getRemoteAddress() { + return this.remoteAddress; } @Override diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpResponse.java b/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpResponse.java index f25f1df618..020e0fa495 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpResponse.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/RxNettyServerHttpResponse.java @@ -47,18 +47,18 @@ import org.springframework.util.Assert; */ public class RxNettyServerHttpResponse extends AbstractServerHttpResponse { - private final HttpServerResponse response; - private static final ByteBuf FLUSH_SIGNAL = Unpooled.buffer(0, 0); // 8 Kb flush threshold to avoid blocking RxNetty when the send buffer has reached the high watermark private static final long FLUSH_THRESHOLD = 8192; - public RxNettyServerHttpResponse(HttpServerResponse response, - NettyDataBufferFactory dataBufferFactory) { - super(dataBufferFactory); - Assert.notNull(response, "'response' must not be null."); + private final HttpServerResponse response; + + + public RxNettyServerHttpResponse(HttpServerResponse response, NettyDataBufferFactory dataBufferFactory) { + super(dataBufferFactory); + Assert.notNull(response, "HttpServerResponse must not be null"); this.response = response; } @@ -113,8 +113,12 @@ public class RxNettyServerHttpResponse extends AbstractServerHttpResponse { if (!httpCookie.getMaxAge().isNegative()) { cookie.setMaxAge(httpCookie.getMaxAge().getSeconds()); } - httpCookie.getDomain().ifPresent(cookie::setDomain); - httpCookie.getPath().ifPresent(cookie::setPath); + if (httpCookie.getDomain() != null) { + cookie.setDomain(httpCookie.getDomain()); + } + if (httpCookie.getPath() != null) { + cookie.setPath(httpCookie.getPath()); + } cookie.setSecure(httpCookie.isSecure()); cookie.setHttpOnly(httpCookie.isHttpOnly()); this.response.addCookie(cookie); diff --git a/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpRequest.java b/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpRequest.java index 1873ee9709..8d2504900b 100644 --- a/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpRequest.java +++ b/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.mock.http.server.reactive.test; import java.net.InetSocketAddress; @@ -22,7 +23,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; -import java.util.Optional; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -66,8 +66,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { private MockServerHttpRequest(HttpMethod httpMethod, URI uri, String contextPath, HttpHeaders headers, MultiValueMap cookies, - InetSocketAddress remoteAddress, - Publisher body) { + InetSocketAddress remoteAddress, Publisher body) { super(uri, headers); this.httpMethod = httpMethod; @@ -89,8 +88,8 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override - public Optional getRemoteAddress() { - return Optional.ofNullable(this.remoteAddress); + public InetSocketAddress getRemoteAddress() { + return this.remoteAddress; } @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java b/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java index 2650b7f43e..6e661b9be7 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/HandlerResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.web.reactive; -import java.util.Optional; import java.util.function.Function; import reactor.core.publisher.Mono; @@ -82,10 +81,10 @@ public class HandlerResult { } /** - * Return the value returned from the handler wrapped as {@link Optional}. + * Return the value returned from the handler, if any. */ - public Optional getReturnValue() { - return Optional.ofNullable(this.returnValue); + public Object getReturnValue() { + return this.returnValue; } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java index d5addc01ed..6297592078 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,12 +86,14 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport @Override protected Validator getValidator() { - return this.configurers.getValidator().orElse(super.getValidator()); + Validator validator = this.configurers.getValidator(); + return (validator != null ? validator : super.getValidator()); } @Override protected MessageCodesResolver getMessageCodesResolver() { - return this.configurers.getMessageCodesResolver().orElse(super.getMessageCodesResolver()); + MessageCodesResolver messageCodesResolver = this.configurers.getMessageCodesResolver(); + return (messageCodesResolver != null ? messageCodesResolver : super.getMessageCodesResolver()); } @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurer.java index abae19f7fc..71bd17bea2 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurer.java @@ -16,8 +16,6 @@ package org.springframework.web.reactive.config; -import java.util.Optional; - import org.springframework.core.convert.converter.Converter; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; @@ -104,17 +102,16 @@ public interface WebFluxConfigurer { *

By default a validator for standard bean validation is created if * bean validation api is present on the classpath. */ - default Optional getValidator() { - return Optional.empty(); + default Validator getValidator() { + return null; } /** - * Provide a custom {@link MessageCodesResolver} to use for data binding - * instead of the one created by default in - * {@link org.springframework.validation.DataBinder}. + * Provide a custom {@link MessageCodesResolver} to use for data binding instead + * of the one created by default in {@link org.springframework.validation.DataBinder}. */ - default Optional getMessageCodesResolver() { - return Optional.empty(); + default MessageCodesResolver getMessageCodesResolver() { + return null; } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurerComposite.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurerComposite.java index b6a72713a0..67bab03662 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurerComposite.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurerComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.web.reactive.config; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -85,12 +84,12 @@ public class WebFluxConfigurerComposite implements WebFluxConfigurer { } @Override - public Optional getValidator() { + public Validator getValidator() { return createSingleBean(WebFluxConfigurer::getValidator, Validator.class); } @Override - public Optional getMessageCodesResolver() { + public MessageCodesResolver getMessageCodesResolver() { return createSingleBean(WebFluxConfigurer::getMessageCodesResolver, MessageCodesResolver.class); } @@ -99,14 +98,10 @@ public class WebFluxConfigurerComposite implements WebFluxConfigurer { this.delegates.forEach(delegate -> delegate.configureViewResolvers(registry)); } - private Optional createSingleBean(Function> factory, - Class beanType) { - - List> result = this.delegates.stream() - .map(factory).filter(Optional::isPresent).collect(Collectors.toList()); - + private T createSingleBean(Function factory, Class beanType) { + List result = this.delegates.stream().map(factory).filter(t -> t != null).collect(Collectors.toList()); if (result.isEmpty()) { - return Optional.empty(); + return null; } else if (result.size() == 1) { return result.get(0); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/UnsupportedMediaTypeException.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/UnsupportedMediaTypeException.java index 4f53dbf084..5cc0a5cc77 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/UnsupportedMediaTypeException.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/UnsupportedMediaTypeException.java @@ -57,10 +57,11 @@ public class UnsupportedMediaTypeException extends NestedRuntimeException { /** - * Return the request Content-Type header if it was parsed successfully. + * Return the request Content-Type header if it was parsed successfully, + * or {@code null} otherwise. */ - public Optional getContentType() { - return Optional.ofNullable(this.contentType); + public MediaType getContentType() { + return this.contentType; } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java index 767623960b..ba563a0197 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java @@ -57,10 +57,10 @@ import org.springframework.web.server.WebSession; class DefaultServerRequest implements ServerRequest { private static final Function ERROR_MAPPER = - ex -> ex.getContentType() - .map(contentType -> new UnsupportedMediaTypeStatusException(contentType, - ex.getSupportedMediaTypes())) - .orElseGet(() -> new UnsupportedMediaTypeStatusException(ex.getMessage())); + ex -> (ex.getContentType() != null ? + new UnsupportedMediaTypeStatusException(ex.getContentType(), ex.getSupportedMediaTypes()) : + new UnsupportedMediaTypeStatusException(ex.getMessage())); + private final ServerWebExchange exchange; @@ -69,8 +69,7 @@ class DefaultServerRequest implements ServerRequest { private final Supplier>> messageReaders; - DefaultServerRequest(ServerWebExchange exchange, - Supplier>> messageReaders) { + DefaultServerRequest(ServerWebExchange exchange, Supplier>> messageReaders) { this.exchange = exchange; this.messageReaders = messageReaders; this.headers = new DefaultHeaders(); @@ -106,12 +105,10 @@ class DefaultServerRequest implements ServerRequest { public Supplier>> messageReaders() { return DefaultServerRequest.this.messageReaders; } - @Override public Optional serverResponse() { return Optional.of(exchange().getResponse()); } - @Override public Map hints() { return hints; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerResponseResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerResponseResultHandler.java index 5496812b62..bcfccde421 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerResponseResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerResponseResultHandler.java @@ -54,14 +54,13 @@ public class ServerResponseResultHandler implements HandlerResultHandler { @Override public boolean supports(HandlerResult result) { - return result.getReturnValue() - .filter(o -> o instanceof ServerResponse) - .isPresent(); + return (result.getReturnValue() instanceof ServerResponse); } @Override public Mono handleResult(ServerWebExchange exchange, HandlerResult result) { - ServerResponse response = (ServerResponse) result.getReturnValue().orElseThrow(IllegalStateException::new); + ServerResponse response = (ServerResponse) result.getReturnValue(); + Assert.state(response != null, "No ServerResponse"); return response.writeTo(exchange, this.strategies); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContext.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContext.java index be6b472bc9..c053ed5b50 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContext.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContext.java @@ -19,7 +19,6 @@ package org.springframework.web.reactive.result.method.annotation; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Optional; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.support.WebBindingInitializer; @@ -69,17 +68,15 @@ class InitBinderBindingContext extends BindingContext { private void invokeBinderMethod(WebExchangeDataBinder dataBinder, ServerWebExchange exchange, SyncInvocableHandlerMethod binderMethod) { - Optional returnValue = binderMethod - .invokeForHandlerResult(exchange, this.binderMethodContext, dataBinder) + Object returnValue = binderMethod.invokeForHandlerResult(exchange, this.binderMethodContext, dataBinder) .getReturnValue(); - if (returnValue.isPresent()) { + if (returnValue != null) { throw new IllegalStateException( "@InitBinder methods should return void: " + binderMethod); } // Should not happen (no Model argument resolution) ... - if (!this.binderMethodContext.getModel().asMap().isEmpty()) { throw new IllegalStateException( "@InitBinder methods should not add model attributes: " + binderMethod); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelInitializer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelInitializer.java index f59f688daf..b7ec5cdd2a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelInitializer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelInitializer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.method.annotation; import java.util.ArrayList; @@ -36,7 +37,6 @@ import org.springframework.web.reactive.HandlerResult; import org.springframework.web.reactive.result.method.InvocableHandlerMethod; import org.springframework.web.server.ServerWebExchange; - /** * Package-private class to assist {@link RequestMappingHandlerAdapter} with * default model initialization through {@code @ModelAttribute} methods. @@ -54,24 +54,16 @@ class ModelInitializer { } - private ReactiveAdapterRegistry getAdapterRegistry() { - return this.adapterRegistry; - } - - /** * Initialize the default model in the given {@code BindingContext} through * the {@code @ModelAttribute} methods and indicate when complete. - * *

This will wait for {@code @ModelAttribute} methods that return * {@code Mono} since those may be adding attributes asynchronously. * However if methods return async attributes, those will be added to the * model as-is and without waiting for them to be resolved. - * * @param bindingContext the BindingContext with the default model * @param attributeMethods the {@code @ModelAttribute} methods * @param exchange the current exchange - * * @return a {@code Mono} for when the model is populated. */ @SuppressWarnings("Convert2MethodRef") @@ -90,28 +82,20 @@ class ModelInitializer { } private Mono handleResult(HandlerResult handlerResult, BindingContext bindingContext) { - - return handlerResult.getReturnValue() - .map(value -> { - ResolvableType type = handlerResult.getReturnType(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.getRawClass(), value); - - Class attributeType; - if (adapter != null) { - attributeType = adapter.isNoValue() ? Void.class : type.resolveGeneric(0); - if (attributeType.equals(Void.class)) { - return Mono.from(adapter.toPublisher(value)); - } - } - else { - attributeType = type.resolve(); - } - - String name = getAttributeName(handlerResult.getReturnTypeSource()); - bindingContext.getModel().asMap().putIfAbsent(name, value); - return Mono.empty(); - }) - .orElse(Mono.empty()); + Object value = handlerResult.getReturnValue(); + if (value != null) { + ResolvableType type = handlerResult.getReturnType(); + ReactiveAdapter adapter = this.adapterRegistry.getAdapter(type.getRawClass(), value); + if (adapter != null) { + Class attributeType = (adapter.isNoValue() ? Void.class : type.resolveGeneric()); + if (attributeType == Void.class) { + return Mono.from(adapter.toPublisher(value)); + } + } + String name = getAttributeName(handlerResult.getReturnTypeSource()); + bindingContext.getModel().asMap().putIfAbsent(name, value); + } + return Mono.empty(); } private String getAttributeName(MethodParameter param) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java index d0ccd3c65b..8439d6ad47 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import org.springframework.web.reactive.HandlerResultHandler; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.server.ServerWebExchange; - /** * {@code HandlerResultHandler} that handles return values from methods annotated * with {@code @ResponseBody} writing to the body of the request or response with @@ -47,9 +46,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Arjen Poutsma * @since 5.0 */ -public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandler - implements HandlerResultHandler { - +public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandler implements HandlerResultHandler { /** * Basic constructor with a default {@link ReactiveAdapterRegistry}. @@ -86,7 +83,7 @@ public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandle @Override public Mono handleResult(ServerWebExchange exchange, HandlerResult result) { - Object body = result.getReturnValue().orElse(null); + Object body = result.getReturnValue(); MethodParameter bodyTypeParameter = result.getReturnTypeSource(); return writeBody(body, bodyTypeParameter, exchange); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java index 34cbcfee64..174fd04357 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.beans.PropertyEditor; @@ -99,7 +100,7 @@ public class BindStatus { this.expression = path.substring(dotPos + 1); } - this.errors = requestContext.getErrors(beanName, false).orElse(null); + this.errors = requestContext.getErrors(beanName, false); if (this.errors != null) { // Usual case: A BindingResult is available as request attribute. diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultRendering.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultRendering.java index 4d1330c2bf..67b7283060 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultRendering.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultRendering.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.Collections; import java.util.Map; -import java.util.Optional; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -47,13 +47,13 @@ class DefaultRendering implements Rendering { this.view = view; this.model = (model != null ? model.asMap() : Collections.emptyMap()); this.status = status; - this.headers = headers != null ? headers : EMPTY_HEADERS; + this.headers = (headers != null ? headers : EMPTY_HEADERS); } @Override - public Optional view() { - return Optional.ofNullable(this.view); + public Object view() { + return this.view; } @Override @@ -62,8 +62,8 @@ class DefaultRendering implements Rendering { } @Override - public Optional status() { - return Optional.ofNullable(this.status); + public HttpStatus status() { + return this.status; } @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java index de41b81e7e..590cce525c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/Rendering.java @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.Collection; import java.util.Map; -import java.util.Optional; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.ui.Model; - /** * Public API for HTML rendering. Supported as a return value in Spring WebFlux * controllers. Comparable to the use of {@code ModelAndView} as a return value @@ -46,7 +45,7 @@ public interface Rendering { /** * Return the selected {@link String} view name or {@link View} object. */ - Optional view(); + Object view(); /** * Return attributes to add to the model. @@ -56,7 +55,7 @@ public interface Rendering { /** * Return the HTTP status to set the response to. */ - Optional status(); + HttpStatus status(); /** * Return headers to add to the response. diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java index 5245c78790..5a6057858c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.TimeZone; import org.springframework.context.MessageSource; @@ -170,8 +169,8 @@ public class RequestContext { * Return the {@link RequestDataValueProcessor} instance to apply to in form * tag libraries and to redirect URLs. */ - public Optional getRequestDataValueProcessor() { - return Optional.ofNullable(this.dataValueProcessor); + public RequestDataValueProcessor getRequestDataValueProcessor() { + return this.dataValueProcessor; } /** @@ -346,7 +345,7 @@ public class RequestContext { * @param name name of the bind object * @return the Errors instance, or {@code null} if not found */ - public Optional getErrors(String name) { + public Errors getErrors(String name) { return getErrors(name, isDefaultHtmlEscape()); } @@ -356,34 +355,28 @@ public class RequestContext { * @param htmlEscape create an Errors instance with automatic HTML escaping? * @return the Errors instance, or {@code null} if not found */ - public Optional getErrors(String name, boolean htmlEscape) { + public Errors getErrors(String name, boolean htmlEscape) { if (this.errorsMap == null) { this.errorsMap = new HashMap<>(); } - // Since there is no Optional orElse + flatMap... - Optional optional = Optional.ofNullable(this.errorsMap.get(name)); - optional = optional.isPresent() ? optional : getModelObject(BindingResult.MODEL_KEY_PREFIX + name); + Errors errors = this.errorsMap.get(name); + if (errors == null) { + errors = getModelObject(BindingResult.MODEL_KEY_PREFIX + name); + } + if (errors instanceof BindException) { + errors = ((BindException) errors).getBindingResult(); + } - return optional - .map(errors -> { - if (errors instanceof BindException) { - return ((BindException) errors).getBindingResult(); - } - else { - return errors; - } - }) - .map(errors -> { - if (htmlEscape && !(errors instanceof EscapedErrors)) { - errors = new EscapedErrors(errors); - } - else if (!htmlEscape && errors instanceof EscapedErrors) { - errors = ((EscapedErrors) errors).getSource(); - } - this.errorsMap.put(name, errors); - return errors; - }); + if (htmlEscape && !(errors instanceof EscapedErrors)) { + errors = new EscapedErrors(errors); + } + else if (!htmlEscape && errors instanceof EscapedErrors) { + errors = ((EscapedErrors) errors).getSource(); + } + + this.errorsMap.put(name, errors); + return errors; } /** @@ -393,10 +386,12 @@ public class RequestContext { * @return the model object */ @SuppressWarnings("unchecked") - protected Optional getModelObject(String modelName) { - return Optional.ofNullable(this.model) - .map(model -> Optional.ofNullable((T) model.get(modelName))) - .orElse(this.exchange.getAttribute(modelName)); + protected T getModelObject(String modelName) { + T modelObject = (T) this.model.get(modelName); + if (modelObject == null) { + modelObject = (T) this.exchange.getAttribute(modelName); + } + return modelObject; } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index 2787139883..cce5d2ab6b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -36,9 +36,9 @@ import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.ui.Model; -import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; @@ -56,13 +56,13 @@ import org.springframework.web.server.support.HttpRequestPathHelper; * {@code HandlerResultHandler} that encapsulates the view resolution algorithm * supporting the following return types: *
    - *
  • {@link Void} or no value -- default view name
  • - *
  • {@link String} -- view name unless {@code @ModelAttribute}-annotated - *
  • {@link View} -- View to render with - *
  • {@link Model} -- attributes to add to the model - *
  • {@link Map} -- attributes to add to the model - *
  • {@link ModelAttribute @ModelAttribute} -- attribute for the model - *
  • Non-simple value -- attribute for the model + *
  • {@link Void} or no value -- default view name
  • + *
  • {@link String} -- view name unless {@code @ModelAttribute}-annotated + *
  • {@link View} -- View to render with + *
  • {@link Model} -- attributes to add to the model + *
  • {@link Map} -- attributes to add to the model + *
  • {@link ModelAttribute @ModelAttribute} -- attribute for the model + *
  • Non-simple value -- attribute for the model *
* *

A String-based view name is resolved through the configured @@ -150,14 +150,16 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport if (hasModelAnnotation(result.getReturnTypeSource())) { return true; } + Class type = result.getReturnType().getRawClass(); ReactiveAdapter adapter = getAdapter(result); if (adapter != null) { if (adapter.isNoValue()) { return true; } - type = result.getReturnType().getGeneric(0).resolve(Object.class); + type = result.getReturnType().getGeneric().resolve(Object.class); } + return (CharSequence.class.isAssignableFrom(type) || Rendering.class.isAssignableFrom(type) || Model.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) || void.class.equals(type) || View.class.isAssignableFrom(type) || @@ -171,22 +173,21 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport @Override @SuppressWarnings("unchecked") public Mono handleResult(ServerWebExchange exchange, HandlerResult result) { - Mono valueMono; ResolvableType valueType; ReactiveAdapter adapter = getAdapter(result); if (adapter != null) { - Assert.isTrue(!adapter.isMultiValue(), "Multi-value " + - "reactive types not supported in view resolution: " + result.getReturnType()); + if (adapter.isMultiValue()) { + throw new IllegalArgumentException( + "Multi-value reactive types not supported in view resolution: " + result.getReturnType()); + } - valueMono = result.getReturnValue() - .map(value -> Mono.from(adapter.toPublisher(value))) - .orElse(Mono.empty()); + valueMono = (result.getReturnValue() != null ? + Mono.from(adapter.toPublisher(result.getReturnValue())) : Mono.empty()); - valueType = adapter.isNoValue() ? - ResolvableType.forClass(Void.class) : - result.getReturnType().getGeneric(0); + valueType = (adapter.isNoValue() ? ResolvableType.forClass(Void.class) : + result.getReturnType().getGeneric()); } else { valueMono = Mono.justOrEmpty(result.getReturnValue()); @@ -217,10 +218,16 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport } else if (Rendering.class.isAssignableFrom(clazz)) { Rendering render = (Rendering) returnValue; - render.status().ifPresent(exchange.getResponse()::setStatusCode); + HttpStatus status = render.status(); + if (status != null) { + exchange.getResponse().setStatusCode(status); + } exchange.getResponse().getHeaders().putAll(render.headers()); model.addAllAttributes(render.modelAttributes()); - Object view = render.view().orElse(getDefaultViewName(exchange)); + Object view = render.view(); + if (view == null) { + view = getDefaultViewName(exchange); + } viewsMono = (view instanceof String ? resolveViews((String) view, locale) : Mono.just(Collections.singletonList((View) view))); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/HandshakeInfo.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/HandshakeInfo.java index 04013021f7..85b06093b8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/HandshakeInfo.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/HandshakeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket; import java.net.URI; import java.security.Principal; -import java.util.Optional; import reactor.core.publisher.Mono; @@ -32,7 +32,6 @@ import org.springframework.util.Assert; * @since 5.0 * @see WebSocketSession#getHandshakeInfo() */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class HandshakeInfo { private final URI uri; @@ -41,7 +40,7 @@ public class HandshakeInfo { private final HttpHeaders headers; - private final Optional protocol; + private final String protocol; /** @@ -49,13 +48,12 @@ public class HandshakeInfo { * @param uri the endpoint URL * @param headers request headers for server or response headers or client * @param principal the principal for the session - * @param protocol the negotiated sub-protocol + * @param protocol the negotiated sub-protocol (may be {@code null}) */ - public HandshakeInfo(URI uri, HttpHeaders headers, Mono principal, Optional protocol) { - Assert.notNull(uri, "URI is required."); - Assert.notNull(headers, "HttpHeaders are required."); - Assert.notNull(principal, "Principal is required."); - Assert.notNull(protocol, "Sub-protocol is required."); + public HandshakeInfo(URI uri, HttpHeaders headers, Mono principal, String protocol) { + Assert.notNull(uri, "URI is required"); + Assert.notNull(headers, "HttpHeaders are required"); + Assert.notNull(principal, "Principal is required"); this.uri = uri; this.headers = headers; this.principalMono = principal; @@ -86,11 +84,11 @@ public class HandshakeInfo { } /** - * The sub-protocol negotiated at handshake time. + * The sub-protocol negotiated at handshake time, or {@code null} if none. * @see - * https://tools.ietf.org/html/rfc6455#section-1.9 + * https://tools.ietf.org/html/rfc6455#section-1.9 */ - public Optional getSubProtocol() { + public String getSubProtocol() { return this.protocol; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java index 20f24371d1..8a45253b95 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/WebSocketHandler.java @@ -13,8 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket; +import java.util.Collections; +import java.util.List; + import reactor.core.publisher.Mono; /** @@ -27,10 +31,10 @@ public interface WebSocketHandler { /** * Return the list of sub-protocols supported by this handler. - *

By default an empty array is returned. + *

By default an empty list is returned. */ - default String[] getSubProtocols() { - return new String[0]; + default List getSubProtocols() { + return Collections.emptyList(); } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java index 1ac6a8b374..3ea6f94a53 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/JettyWebSocketClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.web.reactive.socket.client; import java.net.URI; +import java.util.List; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; @@ -154,7 +155,7 @@ public class JettyWebSocketClient extends WebSocketClientSupport implements WebS MonoProcessor completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { - String[] protocols = beforeHandshake(url, headers, handler); + List protocols = beforeHandshake(url, headers, handler); ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest(); upgradeRequest.setSubProtocols(protocols); Object jettyHandler = createJettyHandler(url, handler, completionMono); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/ReactorNettyWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/ReactorNettyWebSocketClient.java index a4a2aca435..e5fe8b9775 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/ReactorNettyWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/ReactorNettyWebSocketClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.web.reactive.socket.client; import java.net.URI; +import java.util.List; import java.util.function.Consumer; import io.netty.buffer.ByteBufAllocator; @@ -74,13 +75,12 @@ public class ReactorNettyWebSocketClient extends WebSocketClientSupport implemen @Override public Mono execute(URI url, HttpHeaders headers, WebSocketHandler handler) { - - String[] protocols = beforeHandshake(url, headers, handler); + List protocols = beforeHandshake(url, headers, handler); return getHttpClient() .ws(url.toString(), nettyHeaders -> setNettyHeaders(headers, nettyHeaders), - StringUtils.arrayToCommaDelimitedString(protocols)) + StringUtils.collectionToCommaDelimitedString(protocols)) .flatMap(response -> { HandshakeInfo info = afterHandshake(url, toHttpHeaders(response)); ByteBufAllocator allocator = response.channel().alloc(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java index 61509c33c5..e0cf29e148 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/StandardWebSocketClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.web.reactive.socket.client; import java.net.URI; -import java.util.Arrays; import java.util.List; import java.util.Map; import javax.websocket.ClientEndpointConfig; @@ -94,10 +93,10 @@ public class StandardWebSocketClient extends WebSocketClientSupport implements W MonoProcessor completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { - String[] subProtocols = beforeHandshake(url, requestHeaders, handler); + List protocols = beforeHandshake(url, requestHeaders, handler); DefaultConfigurator configurator = new DefaultConfigurator(requestHeaders); Endpoint endpoint = createEndpoint(url, handler, completionMono, configurator); - ClientEndpointConfig config = createEndpointConfig(configurator, subProtocols); + ClientEndpointConfig config = createEndpointConfig(configurator, protocols); return this.webSocketContainer.connectToServer(endpoint, config, url); }) .subscribeOn(Schedulers.elastic()) // connectToServer is blocking @@ -114,10 +113,10 @@ public class StandardWebSocketClient extends WebSocketClientSupport implements W }); } - private ClientEndpointConfig createEndpointConfig(Configurator configurator, String[] subProtocols) { + private ClientEndpointConfig createEndpointConfig(Configurator configurator, List subProtocols) { return ClientEndpointConfig.Builder.create() .configurator(configurator) - .preferredSubprotocols(Arrays.asList(subProtocols)) + .preferredSubprotocols(subProtocols) .build(); } @@ -128,12 +127,10 @@ public class StandardWebSocketClient extends WebSocketClientSupport implements W private final HttpHeaders responseHeaders = new HttpHeaders(); - public DefaultConfigurator(HttpHeaders requestHeaders) { this.requestHeaders = requestHeaders; } - public HttpHeaders getResponseHeaders() { return this.responseHeaders; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/UndertowWebSocketClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/UndertowWebSocketClient.java index 85dfe8eb29..163185595d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/UndertowWebSocketClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/UndertowWebSocketClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.web.reactive.socket.client; import java.io.IOException; import java.net.URI; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -132,18 +131,15 @@ public class UndertowWebSocketClient extends WebSocketClientSupport implements W return Mono.fromCallable( () -> { ConnectionBuilder builder = createConnectionBuilder(url); - String[] protocols = beforeHandshake(url, headers, handler); + List protocols = beforeHandshake(url, headers, handler); DefaultNegotiation negotiation = new DefaultNegotiation(protocols, headers, builder); builder.setClientNegotiation(negotiation); - return builder.connect().addNotifier( new IoFuture.HandlingNotifier() { - @Override public void handleDone(WebSocketChannel channel, Object attachment) { handleChannel(url, handler, completion, negotiation, channel); } - @Override public void handleFailed(IOException ex, Object attachment) { completion.onError(new IllegalStateException("Failed to connect", ex)); @@ -161,11 +157,9 @@ public class UndertowWebSocketClient extends WebSocketClientSupport implements W * provided at construction time. */ protected ConnectionBuilder createConnectionBuilder(URI url) { - ConnectionBuilder builder = io.undertow.websockets.client.WebSocketClient .connectionBuilder(getXnioWorker(), new DefaultByteBufferPool(false, getPoolBufferSize()), url); - this.builderConsumer.accept(builder); return builder; } @@ -192,11 +186,10 @@ public class UndertowWebSocketClient extends WebSocketClientSupport implements W private final WebSocketClientNegotiation delegate; - - public DefaultNegotiation(String[] protocols, HttpHeaders requestHeaders, + public DefaultNegotiation(List protocols, HttpHeaders requestHeaders, ConnectionBuilder connectionBuilder) { - super(Arrays.asList(protocols), Collections.emptyList()); + super(protocols, Collections.emptyList()); this.requestHeaders = requestHeaders; this.delegate = connectionBuilder.getClientNegotiation(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClientSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClientSupport.java index 37619ea81c..dfdb36f294 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClientSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/client/WebSocketClientSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.client; import java.net.URI; -import java.util.Optional; +import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -40,7 +41,7 @@ public class WebSocketClientSupport { protected final Log logger = LogFactory.getLog(getClass()); - protected String[] beforeHandshake(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { + protected List beforeHandshake(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { if (logger.isDebugEnabled()) { logger.debug("Executing handshake to " + url); } @@ -52,7 +53,7 @@ public class WebSocketClientSupport { logger.debug("Handshake response: " + url + ", " + responseHeaders); } String protocol = responseHeaders.getFirst(SEC_WEBSOCKET_PROTOCOL); - return new HandshakeInfo(url, responseHeaders, Mono.empty(), Optional.ofNullable(protocol)); + return new HandshakeInfo(url, responseHeaders, Mono.empty(), protocol); } -} \ No newline at end of file +} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java index 1e0fbd513f..35654ce806 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.web.reactive.socket.server; -import java.util.Optional; +package org.springframework.web.reactive.socket.server; import reactor.core.publisher.Mono; @@ -46,8 +45,6 @@ public interface RequestUpgradeStrategy { * @return completion {@code Mono} to indicate the outcome of the * WebSocket session handling. */ - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - Mono upgrade(ServerWebExchange exchange, WebSocketHandler webSocketHandler, - Optional subProtocol); + Mono upgrade(ServerWebExchange exchange, WebSocketHandler webSocketHandler, String subProtocol); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java index d9cda67fcd..c9c39e3d0f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/support/HandshakeWebSocketService.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.support; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -93,7 +92,7 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle { * @param upgradeStrategy the strategy to use */ public HandshakeWebSocketService(RequestUpgradeStrategy upgradeStrategy) { - Assert.notNull(upgradeStrategy, "'upgradeStrategy' is required"); + Assert.notNull(upgradeStrategy, "RequestUpgradeStrategy is required"); this.upgradeStrategy = upgradeStrategy; } @@ -197,7 +196,7 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle { return handleBadRequest("Missing \"Sec-WebSocket-Key\" header"); } - Optional protocol = selectProtocol(headers, handler); + String protocol = selectProtocol(headers, handler); return this.upgradeStrategy.upgrade(exchange, handler, protocol); } @@ -208,15 +207,17 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle { return Mono.error(new ServerWebInputException(reason)); } - private Optional selectProtocol(HttpHeaders headers, WebSocketHandler handler) { + private String selectProtocol(HttpHeaders headers, WebSocketHandler handler) { String protocolHeader = headers.getFirst(SEC_WEBSOCKET_PROTOCOL); - if (protocolHeader == null) { - return Optional.empty(); + if (protocolHeader != null) { + List supportedProtocols = handler.getSubProtocols(); + for (String protocol : StringUtils.commaDelimitedListToStringArray(protocolHeader)) { + if (supportedProtocols.contains(protocol)) { + return protocol; + } + } } - String[] protocols = handler.getSubProtocols(); - return StringUtils.commaDelimitedListToSet(protocolHeader).stream() - .filter(protocol -> Arrays.stream(protocols).anyMatch(protocol::equals)) - .findFirst(); + return null; } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java index e2ee4d4abc..2a476d8689 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java @@ -18,7 +18,6 @@ package org.springframework.web.reactive.socket.server.upgrade; import java.io.IOException; import java.security.Principal; -import java.util.Optional; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -48,7 +47,6 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 5.0 */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle { private static final ThreadLocal adapterHolder = @@ -73,7 +71,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life this.factory = new WebSocketServerFactory(this.servletContext); this.factory.setCreator((request, response) -> { WebSocketHandlerContainer container = adapterHolder.get(); - String protocol = container.getProtocol().orElse(null); + String protocol = container.getProtocol(); if (protocol != null) { response.setAcceptedSubProtocol(protocol); } @@ -110,9 +108,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, - Optional subProtocol) { - + public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, String subProtocol) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); @@ -155,7 +151,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life return ((ServletServerHttpResponse) response).getServletResponse(); } - private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, Optional protocol) { + private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, String protocol) { ServerHttpRequest request = exchange.getRequest(); Mono principal = exchange.getPrincipal(); return new HandshakeInfo(request.getURI(), request.getHeaders(), principal, protocol); @@ -178,9 +174,9 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life private final JettyWebSocketHandlerAdapter adapter; - private final Optional protocol; + private final String protocol; - public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter adapter, Optional protocol) { + public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter adapter, String protocol) { this.adapter = adapter; this.protocol = protocol; } @@ -189,7 +185,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life return this.adapter; } - public Optional getProtocol() { + public String getProtocol() { return this.protocol; } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java index 9d98f31721..4881af63ca 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.upgrade; import java.security.Principal; -import java.util.Optional; import reactor.core.publisher.Mono; @@ -35,23 +35,19 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 5.0 */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class ReactorNettyRequestUpgradeStrategy implements RequestUpgradeStrategy { @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, - Optional subProtocol) { - + public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, String subProtocol) { ReactorServerHttpResponse response = (ReactorServerHttpResponse) exchange.getResponse(); HandshakeInfo info = getHandshakeInfo(exchange, subProtocol); NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory(); - return response.getReactorResponse().sendWebsocket(subProtocol.orElse(null), - (in, out) -> handler.handle( - new ReactorNettyWebSocketSession(in, out, info, bufferFactory))); + return response.getReactorResponse().sendWebsocket(subProtocol, + (in, out) -> handler.handle(new ReactorNettyWebSocketSession(in, out, info, bufferFactory))); } - private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, Optional protocol) { + private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, String protocol) { ServerHttpRequest request = exchange.getRequest(); Mono principal = exchange.getPrincipal(); return new HandshakeInfo(request.getURI(), request.getHeaders(), principal, protocol); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java index 266982db8a..932f0269fd 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/TomcatRequestUpgradeStrategy.java @@ -19,7 +19,6 @@ package org.springframework.web.reactive.socket.server.upgrade; import java.io.IOException; import java.security.Principal; import java.util.Collections; -import java.util.Optional; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -47,14 +46,13 @@ import org.springframework.web.server.ServerWebExchange; * @author Violeta Georgieva * @since 5.0 */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class TomcatRequestUpgradeStrategy implements RequestUpgradeStrategy { private static final String SERVER_CONTAINER_ATTR = "javax.websocket.server.ServerContainer"; @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, Optional subProtocol){ + public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, String subProtocol){ ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); @@ -70,7 +68,7 @@ public class TomcatRequestUpgradeStrategy implements RequestUpgradeStrategy { String requestURI = servletRequest.getRequestURI(); DefaultServerEndpointConfig config = new DefaultServerEndpointConfig(requestURI, endpoint); - config.setSubprotocols(subProtocol.map(Collections::singletonList).orElse(Collections.emptyList())); + config.setSubprotocols(subProtocol != null ? Collections.singletonList(subProtocol) : Collections.emptyList()); try { WsServerContainer container = getContainer(servletRequest); @@ -93,7 +91,7 @@ public class TomcatRequestUpgradeStrategy implements RequestUpgradeStrategy { return ((ServletServerHttpResponse) response).getServletResponse(); } - private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, Optional protocol) { + private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, String protocol) { ServerHttpRequest request = exchange.getRequest(); Mono principal = exchange.getPrincipal(); return new HandshakeInfo(request.getURI(), request.getHeaders(), principal, protocol); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/UndertowRequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/UndertowRequestUpgradeStrategy.java index 52d228753a..b041e682ff 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/UndertowRequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/UndertowRequestUpgradeStrategy.java @@ -20,7 +20,6 @@ import java.net.URI; import java.security.Principal; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.Set; import io.undertow.server.HttpServerExchange; @@ -50,16 +49,15 @@ import org.springframework.web.server.ServerWebExchange; * @author Violeta Georgieva * @since 5.0 */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class UndertowRequestUpgradeStrategy implements RequestUpgradeStrategy { @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, Optional subProtocol) { + public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, String subProtocol) { ServerHttpRequest request = exchange.getRequest(); Assert.isInstanceOf(UndertowServerHttpRequest.class, request, "UndertowServerHttpRequest required"); HttpServerExchange httpExchange = ((UndertowServerHttpRequest) request).getUndertowExchange(); - Set protocols = subProtocol.map(Collections::singleton).orElse(Collections.emptySet()); + Set protocols = (subProtocol != null ? Collections.singleton(subProtocol) : Collections.emptySet()); Hybi13Handshake handshake = new Hybi13Handshake(protocols, false); List handshakes = Collections.singletonList(handshake); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java index 6d3105c761..8e5204f8eb 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java @@ -18,7 +18,6 @@ package org.springframework.web.reactive.config; import java.util.Collections; import java.util.List; -import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -37,13 +36,8 @@ import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.BDDMockito.any; -import static org.mockito.BDDMockito.doAnswer; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.verify; +import static org.junit.Assert.*; +import static org.mockito.BDDMockito.*; /** * Test fixture for {@link DelegatingWebFluxConfiguration} tests. @@ -72,8 +66,8 @@ public class DelegatingWebFluxConfigurationTests { MockitoAnnotations.initMocks(this); delegatingConfig = new DelegatingWebFluxConfiguration(); delegatingConfig.setApplicationContext(new StaticApplicationContext()); - given(webFluxConfigurer.getValidator()).willReturn(Optional.empty()); - given(webFluxConfigurer.getMessageCodesResolver()).willReturn(Optional.empty()); + given(webFluxConfigurer.getValidator()).willReturn(null); + given(webFluxConfigurer.getMessageCodesResolver()).willReturn(null); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/SseHandlerFunctionIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/SseHandlerFunctionIntegrationTests.java index 98693c15b3..24a34fd950 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/SseHandlerFunctionIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/SseHandlerFunctionIntegrationTests.java @@ -98,18 +98,18 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn StepVerifier.create(result) .consumeNextWith( event -> { - assertEquals("0", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("0", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .consumeNextWith( event -> { - assertEquals("1", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("1", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .expectComplete() .verify(Duration.ofSeconds(5L)); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java index c84af7160a..75ad096773 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/InvocableHandlerMethodTests.java @@ -18,7 +18,6 @@ package org.springframework.web.reactive.result.method; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.Optional; import org.junit.Test; import reactor.core.publisher.Mono; @@ -59,7 +58,6 @@ public class InvocableHandlerMethodTests { @Test public void invokeMethodWithNoValue() throws Exception { - Mono resolvedValue = Mono.empty(); Method method = on(TestController.class).mockCall(o -> o.singleArg(null)).method(); Mono mono = invoke(new TestController(), method, resolverFor(resolvedValue)); @@ -69,7 +67,6 @@ public class InvocableHandlerMethodTests { @Test public void invokeMethodWithValue() throws Exception { - Mono resolvedValue = Mono.just("value1"); Method method = on(TestController.class).mockCall(o -> o.singleArg(null)).method(); Mono mono = invoke(new TestController(), method, resolverFor(resolvedValue)); @@ -79,7 +76,6 @@ public class InvocableHandlerMethodTests { @Test public void noMatchingResolver() throws Exception { - Method method = on(TestController.class).mockCall(o -> o.singleArg(null)).method(); Mono mono = invoke(new TestController(), method); @@ -95,7 +91,6 @@ public class InvocableHandlerMethodTests { @Test public void resolverThrowsException() throws Exception { - Mono resolvedValue = Mono.error(new UnsupportedMediaTypeStatusException("boo")); Method method = on(TestController.class).mockCall(o -> o.singleArg(null)).method(); Mono mono = invoke(new TestController(), method, resolverFor(resolvedValue)); @@ -111,7 +106,6 @@ public class InvocableHandlerMethodTests { @Test public void illegalArgumentExceptionIsWrappedWithInvocationDetails() throws Exception { - Mono resolvedValue = Mono.just(1); Method method = on(TestController.class).mockCall(o -> o.singleArg(null)).method(); Mono mono = invoke(new TestController(), method, resolverFor(resolvedValue)); @@ -129,7 +123,6 @@ public class InvocableHandlerMethodTests { @Test public void invocationTargetExceptionIsUnwrapped() throws Exception { - Method method = on(TestController.class).mockCall(TestController::exceptionMethod).method(); Mono mono = invoke(new TestController(), method); @@ -144,7 +137,6 @@ public class InvocableHandlerMethodTests { @Test public void invokeMethodWithResponseStatus() throws Exception { - Method method = on(TestController.class).annotPresent(ResponseStatus.class).resolveMethod(); Mono mono = invoke(new TestController(), method); @@ -175,9 +167,7 @@ public class InvocableHandlerMethodTests { private void assertHandlerResultValue(Mono mono, String expected) { StepVerifier.create(mono) .consumeNextWith(result -> { - Optional optional = result.getReturnValue(); - assertTrue(optional.isPresent()); - assertEquals(expected, optional.get()); + assertEquals(expected, result.getReturnValue()); }) .expectComplete() .verify(); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java index 5697bd93de..a48cb55555 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -353,10 +352,10 @@ public class RequestMappingInfoHandlerMappingTests { HandlerResult result = mono.block(); assertNotNull(result); - Optional value = result.getReturnValue(); - assertTrue(value.isPresent()); - assertEquals(HttpHeaders.class, value.get().getClass()); - assertEquals(allowedMethods, ((HttpHeaders) value.get()).getAllow()); + Object value = result.getReturnValue(); + assertNotNull(value); + assertEquals(HttpHeaders.class, value.getClass()); + assertEquals(allowedMethods, ((HttpHeaders) value).getAllow()); } private void testMediaTypeNotAcceptable(String url) throws Exception { @@ -490,4 +489,4 @@ public class RequestMappingInfoHandlerMappingTests { } } -} \ No newline at end of file +} diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ControllerAdviceTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ControllerAdviceTests.java index 062aa0d4d6..8a9eaebd9f 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ControllerAdviceTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ControllerAdviceTests.java @@ -91,7 +91,7 @@ public class ControllerAdviceTests { TestController controller = context.getBean(TestController.class); controller.setException(exception); - Object actual = handle(adapter, controller, "handle").getReturnValue().orElse(null); + Object actual = handle(adapter, controller, "handle").getReturnValue(); assertEquals(expected, actual); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java index 77c2550e52..9e005aa27b 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java @@ -37,12 +37,10 @@ import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.springframework.core.ResolvableType.forClassWithGenerics; -import static org.springframework.http.MediaType.TEXT_EVENT_STREAM; -import static org.springframework.web.reactive.function.BodyExtractors.toFlux; - +import static org.junit.Assert.*; +import static org.springframework.core.ResolvableType.*; +import static org.springframework.http.MediaType.*; +import static org.springframework.web.reactive.function.BodyExtractors.*; /** * @author Sebastien Deleuze @@ -112,18 +110,18 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests { StepVerifier.create(result) .consumeNextWith( event -> { - assertEquals("0", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("0", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .consumeNextWith( event -> { - assertEquals("1", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("1", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .thenCancel() .verify(Duration.ofSeconds(5L)); @@ -140,18 +138,18 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests { StepVerifier.create(result) .consumeNextWith( event -> { - assertEquals("0", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("0", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .consumeNextWith( event -> { - assertEquals("1", event.id().get()); - assertEquals("foo", event.data().get()); - assertEquals("bar", event.comment().get()); - assertFalse(event.event().isPresent()); - assertFalse(event.retry().isPresent()); + assertEquals("1", event.id()); + assertEquals("foo", event.data()); + assertEquals("bar", event.comment()); + assertNull(event.event()); + assertNull(event.retry()); }) .thenCancel() .verify(Duration.ofSeconds(5L)); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DefaultRenderingBuilderTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DefaultRenderingBuilderTests.java index 3767b541eb..ec7593df2d 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DefaultRenderingBuilderTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DefaultRenderingBuilderTests.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -23,29 +23,23 @@ import java.util.Map; import org.junit.Test; import org.springframework.http.HttpHeaders; -import org.springframework.ui.ExtendedModelMap; -import org.springframework.ui.Model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * Unit tests for {@link DefaultRenderingBuilder}. + * * @author Rossen Stoyanchev */ public class DefaultRenderingBuilderTests { - @Test public void defaultValues() { Rendering rendering = Rendering.view("abc").build(); - assertEquals("abc", rendering.view().orElse(null)); + assertEquals("abc", rendering.view()); assertEquals(Collections.emptyMap(), rendering.modelAttributes()); - assertNull(rendering.status().orElse(null)); + assertNull(rendering.status()); assertEquals(0, rendering.headers().size()); } @@ -53,7 +47,7 @@ public class DefaultRenderingBuilderTests { public void defaultValuesForRedirect() throws Exception { Rendering rendering = Rendering.redirectTo("abc").build(); - Object view = rendering.view().orElse(null); + Object view = rendering.view(); assertEquals(RedirectView.class, view.getClass()); assertEquals("abc", ((RedirectView) view).getUrl()); assertTrue(((RedirectView) view).isContextRelative()); @@ -64,7 +58,7 @@ public class DefaultRenderingBuilderTests { @Test public void viewName() { Rendering rendering = Rendering.view("foo").build(); - assertEquals("foo", rendering.view().orElse(null)); + assertEquals("foo", rendering.view()); } @Test @@ -118,7 +112,7 @@ public class DefaultRenderingBuilderTests { public void redirectWithAbsoluteUrl() throws Exception { Rendering rendering = Rendering.redirectTo("foo").contextRelative(false).build(); - Object view = rendering.view().orElse(null); + Object view = rendering.view(); assertEquals(RedirectView.class, view.getClass()); assertFalse(((RedirectView) view).isContextRelative()); } @@ -127,7 +121,7 @@ public class DefaultRenderingBuilderTests { public void redirectWithPropagateQuery() throws Exception { Rendering rendering = Rendering.redirectTo("foo").propagateQuery(true).build(); - Object view = rendering.view().orElse(null); + Object view = rendering.view(); assertEquals(RedirectView.class, view.getClass()); assertTrue(((RedirectView) view).isPropagateQuery()); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/WebSocketIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/WebSocketIntegrationTests.java index d6cfebbc12..3526bcb467 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/WebSocketIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/WebSocketIntegrationTests.java @@ -17,7 +17,9 @@ package org.springframework.web.reactive.socket; import java.time.Duration; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -69,19 +71,16 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTests @Test public void subProtocol() throws Exception { - String protocol = "echo-v1"; AtomicReference infoRef = new AtomicReference<>(); MonoProcessor output = MonoProcessor.create(); client.execute(getUrl("/sub-protocol"), new WebSocketHandler() { - @Override - public String[] getSubProtocols() { - return new String[] {protocol}; + public List getSubProtocols() { + return Collections.singletonList(protocol); } - @Override public Mono handle(WebSocketSession session) { infoRef.set(session.getHandshakeInfo()); @@ -96,7 +95,7 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTests HandshakeInfo info = infoRef.get(); assertThat(info.getHeaders().getFirst("Upgrade"), Matchers.equalToIgnoringCase("websocket")); assertEquals(protocol, info.getHeaders().getFirst("Sec-WebSocket-Protocol")); - assertEquals("Wrong protocol accepted", protocol, info.getSubProtocol().orElse("none")); + assertEquals("Wrong protocol accepted", protocol, info.getSubProtocol()); assertEquals("Wrong protocol detected on the server side", protocol, output.block(Duration.ofMillis(5000))); } @@ -122,7 +121,6 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTests @Bean public HandlerMapping handlerMapping() { - Map map = new HashMap<>(); map.put("/echo", new EchoWebSocketHandler()); map.put("/sub-protocol", new SubProtocolWebSocketHandler()); @@ -149,13 +147,13 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTests private static class SubProtocolWebSocketHandler implements WebSocketHandler { @Override - public String[] getSubProtocols() { - return new String[] {"echo-v1"}; + public List getSubProtocols() { + return Collections.singletonList("echo-v1"); } @Override public Mono handle(WebSocketSession session) { - String protocol = session.getHandshakeInfo().getSubProtocol().orElse("none"); + String protocol = session.getHandshakeInfo().getSubProtocol(); WebSocketMessage message = session.textMessage(protocol); return doSend(session, Mono.just(message)); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/client/RxNettyWebSocketClient.java b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/client/RxNettyWebSocketClient.java index b5932914b6..d9c3b71653 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/client/RxNettyWebSocketClient.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/client/RxNettyWebSocketClient.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.client; import java.net.URI; @@ -24,6 +25,7 @@ import java.util.function.Function; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; +import io.reactivex.netty.protocol.http.HttpHandlerNames; import io.reactivex.netty.protocol.http.client.HttpClient; import io.reactivex.netty.protocol.http.client.HttpClientRequest; import io.reactivex.netty.protocol.http.ws.WebSocketConnection; @@ -39,12 +41,11 @@ import rx.RxReactiveStreams; import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.http.HttpHeaders; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; import org.springframework.web.reactive.socket.HandshakeInfo; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.adapter.RxNettyWebSocketSession; -import static io.reactivex.netty.protocol.http.HttpHandlerNames.WsClientDecoder; - /** * {@link WebSocketClient} implementation for use with RxNetty. * For internal use within the framework. @@ -125,7 +126,7 @@ public class RxNettyWebSocketClient extends WebSocketClientSupport implements We @SuppressWarnings("cast") private Observable executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { - String[] protocols = beforeHandshake(url, headers, handler); + List protocols = beforeHandshake(url, headers, handler); return createRequest(url, headers, protocols) .flatMap(response -> { Observable conn = response.getWebSocketConnection(); @@ -141,13 +142,13 @@ public class RxNettyWebSocketClient extends WebSocketClientSupport implements We ByteBufAllocator allocator = response.unsafeNettyChannel().alloc(); NettyDataBufferFactory factory = new NettyDataBufferFactory(allocator); RxNettyWebSocketSession session = new RxNettyWebSocketSession(conn, info, factory); - session.aggregateFrames(response.unsafeNettyChannel(), WsClientDecoder.getName()); + session.aggregateFrames(response.unsafeNettyChannel(), HttpHandlerNames.WsClientDecoder.getName()); return RxReactiveStreams.toObservable(handler.handle(session)); }); } - private WebSocketRequest createRequest(URI url, HttpHeaders headers, String[] protocols) { + private WebSocketRequest createRequest(URI url, HttpHeaders headers, List protocols) { String query = url.getRawQuery(); String requestUrl = url.getRawPath() + (query != null ? "?" + query : ""); HttpClientRequest request = getHttpClient(url).createGet(requestUrl); @@ -158,9 +159,8 @@ public class RxNettyWebSocketClient extends WebSocketClientSupport implements We request = request.setHeaders(map); } - return (ObjectUtils.isEmpty(protocols) ? - request.requestWebSocketUpgrade() : - request.requestWebSocketUpgrade().requestSubProtocols(protocols)); + return (ObjectUtils.isEmpty(protocols) ? request.requestWebSocketUpgrade() : + request.requestWebSocketUpgrade().requestSubProtocols(StringUtils.toStringArray(protocols))); } private HttpHeaders toHttpHeaders(WebSocketResponse response) { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/RxNettyRequestUpgradeStrategy.java b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/RxNettyRequestUpgradeStrategy.java index 64323b1540..811d9f13aa 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/RxNettyRequestUpgradeStrategy.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/socket/server/upgrade/RxNettyRequestUpgradeStrategy.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.server.upgrade; import java.security.Principal; @@ -40,14 +41,10 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 5.0 */ -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class RxNettyRequestUpgradeStrategy implements RequestUpgradeStrategy { - @Override - public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, - Optional subProtocol) { - + public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler, String subProtocol) { RxNettyServerHttpResponse response = (RxNettyServerHttpResponse) exchange.getResponse(); HttpServerResponse rxNettyResponse = response.getRxNettyResponse(); @@ -62,18 +59,18 @@ public class RxNettyRequestUpgradeStrategy implements RequestUpgradeStrategy { return RxReactiveStreams.toObservable(handler.handle(session)); }); - if (subProtocol.isPresent()) { - handshaker = handshaker.subprotocol(subProtocol.get()); + if (subProtocol != null) { + handshaker = handshaker.subprotocol(subProtocol); } else { // TODO: https://github.com/reactor/reactor-netty/issues/20 - handshaker = handshaker.subprotocol(new String[0]); + handshaker = handshaker.subprotocol(); } return Mono.from(RxReactiveStreams.toPublisher(handshaker)); } - private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, Optional protocol) { + private HandshakeInfo getHandshakeInfo(ServerWebExchange exchange, String protocol) { ServerHttpRequest request = exchange.getRequest(); Mono principal = exchange.getPrincipal(); return new HandshakeInfo(request.getURI(), request.getHeaders(), principal, protocol); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java index 7cde9554b2..1787960349 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.servlet.mvc.method.annotation; import java.io.IOException; @@ -50,7 +51,6 @@ import org.springframework.web.context.request.async.WebAsyncUtils; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.servlet.HandlerMapping; - /** * Private helper class to assist with handling "reactive" return values types * that can be adapted to a Reactive Streams {@link Publisher} through the @@ -70,9 +70,6 @@ class ReactiveTypeHandler { private static Log logger = LogFactory.getLog(ReactiveTypeHandler.class); - private static final MediaType JSON_TYPE = new MediaType("application", "*+json"); - - private final ReactiveAdapterRegistry reactiveRegistry; private final TaskExecutor taskExecutor; @@ -100,14 +97,13 @@ class ReactiveTypeHandler { * Whether the type can be adapted to a Reactive Streams {@link Publisher}. */ public boolean isReactiveType(Class type) { - return this.reactiveRegistry.hasAdapters() && this.reactiveRegistry.getAdapter(type) != null; + return (this.reactiveRegistry.hasAdapters() && this.reactiveRegistry.getAdapter(type) != null); } /** * Process the given reactive return value and decide whether to adapt it * to a {@link ResponseBodyEmitter} or a {@link DeferredResult}. - * * @return an emitter for streaming or {@code null} if handled internally * with a {@link DeferredResult}. */ @@ -164,7 +160,6 @@ class ReactiveTypeHandler { private ResponseBodyEmitter getEmitter(MediaType mediaType) { return new ResponseBodyEmitter() { - @Override protected void extendResponse(ServerHttpResponse outputMessage) { outputMessage.getHeaders().setContentType(mediaType); @@ -191,24 +186,20 @@ class ReactiveTypeHandler { private volatile boolean done; - protected AbstractEmitterSubscriber(ResponseBodyEmitter emitter, TaskExecutor executor) { this.emitter = emitter; this.taskExecutor = executor; } - public void connect(ReactiveAdapter adapter, Object returnValue) { Publisher publisher = adapter.toPublisher(returnValue); publisher.subscribe(this); } - protected ResponseBodyEmitter getEmitter() { return this.emitter; } - @Override public final void onSubscribe(Subscription subscription) { this.subscription = subscription; @@ -344,10 +335,18 @@ class ReactiveTypeHandler { private SseEmitter.SseEventBuilder adapt(ServerSentEvent event) { SseEmitter.SseEventBuilder builder = SseEmitter.event(); - event.id().ifPresent(builder::id); - event.comment().ifPresent(builder::comment); - event.data().ifPresent(builder::data); - event.retry().ifPresent(duration -> builder.reconnectTime(duration.toMillis())); + if (event.id() != null) { + builder.id(event.id()); + } + if (event.comment() != null) { + builder.comment(event.comment()); + } + if (event.data() != null) { + builder.data(event.data()); + } + if (event.retry() != null) { + builder.reconnectTime(event.retry().toMillis()); + } return builder; } }