Package private request and response implementations

Concrete server and client, reactive request and response
implementations should not have to be accessed outside their package.
They could be seen as private to their HttpHandler adapters and
ClientHttpConnector's respectively.

The one exception, WebSocket upgrades in spring-webflux, is an internal
framework use case, accommodated via downcast + accessors in the
abstract base classes.
This commit is contained in:
Rossen Stoyanchev
2017-09-29 12:46:32 -04:00
parent 95fdfac128
commit 223e27d53d
25 changed files with 153 additions and 72 deletions

View File

@@ -40,7 +40,7 @@ import org.springframework.http.ZeroCopyHttpOutputMessage;
* @since 5.0
* @see reactor.ipc.netty.http.client.HttpClient
*/
public class ReactorClientHttpRequest extends AbstractClientHttpRequest implements ZeroCopyHttpOutputMessage {
class ReactorClientHttpRequest extends AbstractClientHttpRequest implements ZeroCopyHttpOutputMessage {
private final HttpMethod httpMethod;

View File

@@ -37,7 +37,7 @@ import org.springframework.util.MultiValueMap;
* @since 5.0
* @see reactor.ipc.netty.http.client.HttpClient
*/
public class ReactorClientHttpResponse implements ClientHttpResponse {
class ReactorClientHttpResponse implements ClientHttpResponse {
private final NettyDataBufferFactory dataBufferFactory;

View File

@@ -152,4 +152,11 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
*/
protected abstract MultiValueMap<String, HttpCookie> initCookies();
/**
* Return the underlying server response.
* <p><strong>Note:</strong> This is exposed mainly for internal framework
* use such as WebSocket upgrades in the spring-webflux module.
*/
public abstract <T> T getNativeRequest();
}

View File

@@ -132,6 +132,14 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
}
}
/**
* Return the underlying server response.
* <p><strong>Note:</strong> This is exposed mainly for internal framework
* use such as WebSocket upgrades in the spring-webflux module.
*/
public abstract <T> T getNativeResponse();
@Override
public void beforeCommit(Supplier<? extends Mono<Void>> action) {
this.commitActions.add(action);

View File

@@ -63,6 +63,9 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private Flux<DataBuffer> body;
private final ServerHttpRequest originalRequest;
public DefaultServerHttpRequestBuilder(ServerHttpRequest original) {
Assert.notNull(original, "ServerHttpRequest is required");
@@ -76,6 +79,8 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
this.cookies = new LinkedMultiValueMap<>(original.getCookies().size());
copyMultiValueMap(original.getCookies(), this.cookies);
this.originalRequest = original;
}
private static <K, V> void copyMultiValueMap(MultiValueMap<K,V> source,
@@ -130,7 +135,8 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
public ServerHttpRequest build() {
URI uriToUse = getUriToUse();
return new DefaultServerHttpRequest(uriToUse, this.contextPath, this.httpHeaders,
this.httpMethodValue, this.cookies, this.remoteAddress, this.body);
this.httpMethodValue, this.cookies, this.remoteAddress, this.body,
this.originalRequest);
}
@@ -158,17 +164,23 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private final Flux<DataBuffer> body;
private final ServerHttpRequest originalRequest;
public DefaultServerHttpRequest(URI uri, @Nullable String contextPath,
HttpHeaders headers, String methodValue,
MultiValueMap<String, HttpCookie> cookies, @Nullable InetSocketAddress remoteAddress,
Flux<DataBuffer> body) {
HttpHeaders headers, String methodValue, MultiValueMap<String, HttpCookie> cookies,
@Nullable InetSocketAddress remoteAddress,
Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
super(uri, contextPath, headers);
this.methodValue = methodValue;
this.cookies = cookies;
this.remoteAddress = remoteAddress;
this.body = body;
this.originalRequest = originalRequest;
}
@Override
public String getMethodValue() {
return this.methodValue;
@@ -189,6 +201,12 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
public Flux<DataBuffer> getBody() {
return this.body;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeRequest() {
return (T) this.originalRequest;
}
}
}

View File

@@ -19,6 +19,7 @@ package org.springframework.http.server.reactive;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.servlet.AsyncContext;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletResponse;
@@ -62,7 +63,8 @@ public class JettyHttpHandlerAdapter extends ServletHttpHandlerAdapter {
protected int writeToOutputStream(DataBuffer dataBuffer) throws IOException {
ByteBuffer input = dataBuffer.asByteBuffer();
int len = input.remaining();
((HttpOutput) getServletResponse().getOutputStream()).write(input);
ServletResponse response = getNativeResponse();
((HttpOutput) response.getOutputStream()).write(input);
return len;
}
}

View File

@@ -42,7 +42,7 @@ import org.springframework.util.MultiValueMap;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
class ReactorServerHttpRequest extends AbstractServerHttpRequest {
private final HttpServerRequest request;
@@ -108,11 +108,6 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
return headers;
}
public HttpServerRequest getReactorRequest() {
return this.request;
}
@Override
public String getMethodValue() {
return this.request.method().name();
@@ -140,4 +135,10 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
return this.request.receive().retain().map(this.bufferFactory::wrap);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeRequest() {
return (T) this.request;
}
}

View File

@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ReactorServerHttpResponse extends AbstractServerHttpResponse implements ZeroCopyHttpOutputMessage {
class ReactorServerHttpResponse extends AbstractServerHttpResponse implements ZeroCopyHttpOutputMessage {
private final HttpServerResponse response;
@@ -56,8 +56,10 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse implem
}
public HttpServerResponse getReactorResponse() {
return this.response;
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeResponse() {
return (T) this.response;
}
@@ -65,7 +67,7 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse implem
protected void applyStatusCode() {
HttpStatus statusCode = this.getStatusCode();
if (statusCode != null) {
getReactorResponse().status(HttpResponseStatus.valueOf(statusCode.value()));
this.response.status(HttpResponseStatus.valueOf(statusCode.value()));
}
}

View File

@@ -53,7 +53,7 @@ import org.springframework.util.StringUtils;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ServletServerHttpRequest extends AbstractServerHttpRequest {
class ServletServerHttpRequest extends AbstractServerHttpRequest {
protected final Log logger = LogFactory.getLog(getClass());
@@ -145,13 +145,9 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest {
}
public HttpServletRequest getServletRequest() {
return this.request;
}
@Override
public String getMethodValue() {
return getServletRequest().getMethod();
return this.request.getMethod();
}
@Override
@@ -201,6 +197,12 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest {
return null;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeRequest() {
return (T) this.request;
}
private final class RequestAsyncListener implements AsyncListener {

View File

@@ -47,7 +47,7 @@ import org.springframework.util.Assert;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
private final HttpServletResponse response;
@@ -84,15 +84,17 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
}
public HttpServletResponse getServletResponse() {
return this.response;
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeResponse() {
return (T) this.response;
}
@Override
protected void applyStatusCode() {
HttpStatus statusCode = this.getStatusCode();
if (statusCode != null) {
getServletResponse().setStatus(statusCode.value());
this.response.setStatus(statusCode.value());
}
}

View File

@@ -19,6 +19,8 @@ package org.springframework.http.server.reactive;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.servlet.AsyncContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -69,7 +71,8 @@ public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter {
ByteBuffer byteBuffer = buffer.asByteBuffer();
byteBuffer.limit(byteBuffer.capacity());
int read = ((CoyoteInputStream) getServletRequest().getInputStream()).read(byteBuffer);
ServletRequest request = getNativeRequest();
int read = ((CoyoteInputStream) request.getInputStream()).read(byteBuffer);
if (logger.isTraceEnabled()) {
logger.trace("read:" + read);
}
@@ -95,7 +98,8 @@ public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter {
protected int writeToOutputStream(DataBuffer dataBuffer) throws IOException {
ByteBuffer input = dataBuffer.asByteBuffer();
int len = input.remaining();
((CoyoteOutputStream) getServletResponse().getOutputStream()).write(input);
ServletResponse response = getNativeResponse();
((CoyoteOutputStream) response.getOutputStream()).write(input);
return len;
}
}

View File

@@ -46,7 +46,7 @@ import org.springframework.util.StringUtils;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
class UndertowServerHttpRequest extends AbstractServerHttpRequest {
private final HttpServerExchange exchange;
@@ -76,14 +76,9 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
return headers;
}
public HttpServerExchange getUndertowExchange() {
return this.exchange;
}
@Override
public String getMethodValue() {
return this.getUndertowExchange().getRequestMethod().toString();
return this.exchange.getRequestMethod().toString();
}
@Override
@@ -107,6 +102,12 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
return Flux.from(this.body);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeRequest() {
return (T) this.exchange;
}
private static class RequestBodyPublisher extends AbstractListenerReadPublisher<DataBuffer> {

View File

@@ -51,8 +51,7 @@ import org.springframework.util.Assert;
* @author Arjen Poutsma
* @since 5.0
*/
public class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse
implements ZeroCopyHttpOutputMessage {
class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse implements ZeroCopyHttpOutputMessage {
private final HttpServerExchange exchange;
@@ -67,8 +66,10 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
}
public HttpServerExchange getUndertowExchange() {
return this.exchange;
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeResponse() {
return (T) this.exchange;
}
@@ -76,7 +77,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
protected void applyStatusCode() {
HttpStatus statusCode = this.getStatusCode();
if (statusCode != null) {
getUndertowExchange().setStatusCode(statusCode.value());
this.exchange.setStatusCode(statusCode.value());
}
}
@@ -115,7 +116,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
FileChannel source = null;
try {
source = FileChannel.open(file.toPath(), StandardOpenOption.READ);
StreamSinkChannel destination = getUndertowExchange().getResponseChannel();
StreamSinkChannel destination = this.exchange.getResponseChannel();
Channels.transferBlocking(destination, source, position, count);
return Mono.empty();
}