Merged all Response implementations into one
Merged all *Response implementations into one DefaultResponses class
This commit is contained in:
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
|
||||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
abstract class AbstractHttpMessageWriterResponse<T> extends AbstractResponse<T> {
|
|
||||||
|
|
||||||
protected AbstractHttpMessageWriterResponse(int statusCode, HttpHeaders headers) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <S> Mono<Void> writeToInternal(ServerWebExchange exchange,
|
|
||||||
Publisher<S> body,
|
|
||||||
ResolvableType bodyType) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
|
||||||
ServerHttpResponse response = exchange.getResponse();
|
|
||||||
return messageWriterStream(exchange)
|
|
||||||
.filter(messageWriter -> messageWriter.canWrite(bodyType, contentType, Collections.emptyMap()))
|
|
||||||
.findFirst()
|
|
||||||
.map(CastingUtils::cast)
|
|
||||||
.map(messageWriter -> messageWriter.write(body, bodyType, contentType, response, Collections.emptyMap()))
|
|
||||||
.orElseGet(() -> {
|
|
||||||
response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
|
|
||||||
return response.setComplete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stream<HttpMessageWriter<?>> messageWriterStream(ServerWebExchange exchange) {
|
|
||||||
return exchange.<Supplier<Stream<HttpMessageWriter<?>>>>getAttribute(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE)
|
|
||||||
.orElseThrow(() -> new IllegalStateException("Could not find HttpMessageWriters in ServerWebExchange"))
|
|
||||||
.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
abstract class AbstractResponse<T> implements Response<T> {
|
|
||||||
|
|
||||||
private final int statusCode;
|
|
||||||
|
|
||||||
private final HttpHeaders headers;
|
|
||||||
|
|
||||||
protected AbstractResponse(
|
|
||||||
int statusCode, HttpHeaders headers) {
|
|
||||||
this.statusCode = statusCode;
|
|
||||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpStatus statusCode() {
|
|
||||||
return HttpStatus.valueOf(this.statusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpHeaders headers() {
|
|
||||||
return this.headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeStatusAndHeaders(ServerWebExchange exchange) {
|
|
||||||
ServerHttpResponse response = exchange.getResponse();
|
|
||||||
response.setStatusCode(HttpStatus.valueOf(this.statusCode));
|
|
||||||
HttpHeaders responseHeaders = response.getHeaders();
|
|
||||||
|
|
||||||
if (!this.headers.isEmpty()) {
|
|
||||||
this.headers.entrySet().stream()
|
|
||||||
.filter(entry -> !responseHeaders.containsKey(entry.getKey()))
|
|
||||||
.forEach(entry -> responseHeaders
|
|
||||||
.put(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class BodyResponse<T> extends AbstractHttpMessageWriterResponse<T> {
|
|
||||||
|
|
||||||
private final T body;
|
|
||||||
|
|
||||||
public BodyResponse(int statusCode, HttpHeaders headers,
|
|
||||||
T body) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
Assert.notNull(body, "'body' must not be null");
|
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T body() {
|
|
||||||
return this.body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
return writeToInternal(exchange, Mono.just(this.body), ResolvableType.forInstance(this.body));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -132,47 +132,45 @@ class DefaultResponseBuilder implements Response.BodyBuilder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<Void> build() {
|
public Response<Void> build() {
|
||||||
return new EmptyResponse(this.statusCode, this.headers);
|
return DefaultResponses.empty(this.statusCode, this.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Publisher<Void>> Response<T> build(T voidPublisher) {
|
public <T extends Publisher<Void>> Response<T> build(T voidPublisher) {
|
||||||
Assert.notNull(voidPublisher, "'voidPublisher' must not be null");
|
Assert.notNull(voidPublisher, "'voidPublisher' must not be null");
|
||||||
return new VoidPublisherResponse<>(this.statusCode, this.headers, voidPublisher);
|
return DefaultResponses.empty(this.statusCode, this.headers, voidPublisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> Response<T> body(T body) {
|
public <T> Response<T> body(T body) {
|
||||||
Assert.notNull(body, "'body' must not be null");
|
Assert.notNull(body, "'body' must not be null");
|
||||||
return new BodyResponse<>(this.statusCode, this.headers, body);
|
return DefaultResponses.body(this.statusCode, this.headers, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T, S extends Publisher<T>> Response<S> stream(S publisher, Class<T> elementClass) {
|
public <T, S extends Publisher<T>> Response<S> stream(S publisher, Class<T> elementClass) {
|
||||||
Assert.notNull(publisher, "'publisher' must not be null");
|
Assert.notNull(publisher, "'publisher' must not be null");
|
||||||
Assert.notNull(elementClass, "'elementClass' must not be null");
|
Assert.notNull(elementClass, "'elementClass' must not be null");
|
||||||
return new PublisherResponse<>(this.statusCode, this.headers, publisher, elementClass);
|
return DefaultResponses.stream(this.statusCode, this.headers, publisher, elementClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<Resource> resource(Resource resource) {
|
public Response<Resource> resource(Resource resource) {
|
||||||
Assert.notNull(resource, "'resource' must not be null");
|
Assert.notNull(resource, "'resource' must not be null");
|
||||||
return new ResourceResponse(this.statusCode, this.headers, resource);
|
return DefaultResponses.resource(this.statusCode, this.headers, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T, S extends Publisher<ServerSentEvent<T>>> Response<S> sse(S eventsPublisher) {
|
public <T, S extends Publisher<ServerSentEvent<T>>> Response<S> sse(S eventsPublisher) {
|
||||||
Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null");
|
Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null");
|
||||||
return ServerSentEventResponse
|
return DefaultResponses.sse(this.statusCode, this.headers, eventsPublisher);
|
||||||
.fromSseEvents(this.statusCode, this.headers, eventsPublisher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T, S extends Publisher<T>> Response<S> sse(S eventsPublisher, Class<T> eventClass) {
|
public <T, S extends Publisher<T>> Response<S> sse(S eventsPublisher, Class<T> eventClass) {
|
||||||
Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null");
|
Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null");
|
||||||
Assert.notNull(eventClass, "'eventClass' must not be null");
|
Assert.notNull(eventClass, "'eventClass' must not be null");
|
||||||
return ServerSentEventResponse
|
return DefaultResponses.sse(this.statusCode, this.headers, eventsPublisher, eventClass);
|
||||||
.fromPublisher(this.statusCode, this.headers, eventsPublisher, eventClass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -180,7 +178,11 @@ class DefaultResponseBuilder implements Response.BodyBuilder {
|
|||||||
Map<String, Object> modelMap = Arrays.stream(modelAttributes)
|
Map<String, Object> modelMap = Arrays.stream(modelAttributes)
|
||||||
.filter(o -> !isEmptyCollection(o))
|
.filter(o -> !isEmptyCollection(o))
|
||||||
.collect(Collectors.toMap(Conventions::getVariableName, o -> o));
|
.collect(Collectors.toMap(Conventions::getVariableName, o -> o));
|
||||||
return new RenderingResponse(this.statusCode, this.headers, name, modelMap);
|
return DefaultResponses.render(this.statusCode, this.headers, name, modelMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEmptyCollection(Object o) {
|
||||||
|
return o instanceof Collection && ((Collection<?>) o).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -190,11 +192,7 @@ class DefaultResponseBuilder implements Response.BodyBuilder {
|
|||||||
if (model != null) {
|
if (model != null) {
|
||||||
modelMap.putAll(model);
|
modelMap.putAll(model);
|
||||||
}
|
}
|
||||||
return new RenderingResponse(this.statusCode, this.headers, name, modelMap);
|
return DefaultResponses.render(this.statusCode, this.headers, name, modelMap);
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isEmptyCollection(Object o) {
|
|
||||||
return o instanceof Collection && ((Collection<?>) o).isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2016 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.reactive.function;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.reactivestreams.Publisher;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import org.springframework.core.ResolvableType;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.codec.HttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.ServerSentEvent;
|
||||||
|
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
abstract class DefaultResponses {
|
||||||
|
|
||||||
|
private static final ResolvableType RESOURCE_TYPE = ResolvableType.forClass(Resource.class);
|
||||||
|
|
||||||
|
private static final ResolvableType SERVER_SIDE_EVENT_TYPE =
|
||||||
|
ResolvableType.forClass(ServerSentEvent.class);
|
||||||
|
|
||||||
|
private static final boolean jackson2Present =
|
||||||
|
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||||
|
DefaultConfiguration.class.getClassLoader()) &&
|
||||||
|
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
|
||||||
|
DefaultConfiguration.class.getClassLoader());
|
||||||
|
|
||||||
|
|
||||||
|
public static Response<Void> empty(int statusCode, HttpHeaders headers) {
|
||||||
|
return new DefaultResponse<>(statusCode, headers, null,
|
||||||
|
exchange -> exchange.getResponse().setComplete()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Publisher<Void>> Response<T> empty(int statusCode, HttpHeaders headers,
|
||||||
|
T voidPublisher) {
|
||||||
|
return new DefaultResponse<T>(statusCode, headers, voidPublisher,
|
||||||
|
exchange -> Flux.from(voidPublisher)
|
||||||
|
.then(exchange.getResponse().setComplete()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response<Resource> resource(int statusCode, HttpHeaders headers,
|
||||||
|
Resource resource) {
|
||||||
|
return new DefaultResponse<>(statusCode, headers, resource,
|
||||||
|
exchange -> {
|
||||||
|
ResourceHttpMessageWriter messageWriter = new ResourceHttpMessageWriter();
|
||||||
|
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||||
|
return messageWriter
|
||||||
|
.write(Mono.just(resource), RESOURCE_TYPE, contentType,
|
||||||
|
exchange.getResponse(), Collections.emptyMap());
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Response<T> body(int statusCode, HttpHeaders headers, T body) {
|
||||||
|
return new DefaultResponse<T>(statusCode, headers, body,
|
||||||
|
exchange -> writeWithMessageWriters(exchange, Mono.just(body),
|
||||||
|
ResolvableType.forInstance(body)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <S extends Publisher<T>, T> Response<S> stream(int statusCode,
|
||||||
|
HttpHeaders headers, S publisher,
|
||||||
|
Class<T> elementClass) {
|
||||||
|
return new DefaultResponse<S>(statusCode, headers, publisher,
|
||||||
|
exchange -> writeWithMessageWriters(exchange, publisher,
|
||||||
|
ResolvableType.forClass(elementClass)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, S extends Publisher<ServerSentEvent<T>>> Response<S> sse(int statusCode,
|
||||||
|
HttpHeaders headers, S eventsPublisher) {
|
||||||
|
return new DefaultResponse<S>(statusCode, headers, eventsPublisher,
|
||||||
|
exchange -> {
|
||||||
|
ServerSentEventHttpMessageWriter messageWriter =
|
||||||
|
serverSentEventHttpMessageWriter();
|
||||||
|
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||||
|
return messageWriter
|
||||||
|
.write(eventsPublisher, SERVER_SIDE_EVENT_TYPE, contentType, exchange.getResponse(), Collections
|
||||||
|
.emptyMap());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <S extends Publisher<T>, T> Response<S> sse(int statusCode, HttpHeaders headers,
|
||||||
|
S eventsPublisher,
|
||||||
|
Class<T> eventClass) {
|
||||||
|
return new DefaultResponse<S>(statusCode, headers, eventsPublisher,
|
||||||
|
exchange -> {
|
||||||
|
ServerSentEventHttpMessageWriter messageWriter =
|
||||||
|
serverSentEventHttpMessageWriter();
|
||||||
|
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||||
|
return messageWriter
|
||||||
|
.write(eventsPublisher, ResolvableType.forClass(eventClass), contentType,
|
||||||
|
exchange.getResponse(), Collections.emptyMap());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response<Rendering> render(int statusCode, HttpHeaders headers, String name,
|
||||||
|
Map<String, Object> modelMap) {
|
||||||
|
Rendering defaultRendering = new DefaultRendering(name, modelMap);
|
||||||
|
return new DefaultResponse<>(statusCode, headers, defaultRendering,
|
||||||
|
exchange -> {
|
||||||
|
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||||
|
Locale locale = Locale.ENGLISH; // TODO: resolve locale
|
||||||
|
return Flux.fromStream(viewResolverStream(exchange))
|
||||||
|
.concatMap(viewResolver -> viewResolver.resolveViewName(name, locale))
|
||||||
|
.next()
|
||||||
|
.otherwiseIfEmpty(Mono.error(new IllegalArgumentException("Could not resolve view with name '" + name +"'")))
|
||||||
|
.then(view -> view.render(modelMap, contentType, exchange));
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServerSentEventHttpMessageWriter serverSentEventHttpMessageWriter() {
|
||||||
|
return jackson2Present ? new ServerSentEventHttpMessageWriter(
|
||||||
|
Collections.singletonList(new Jackson2JsonEncoder())) :
|
||||||
|
new ServerSentEventHttpMessageWriter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> Mono<Void> writeWithMessageWriters(ServerWebExchange exchange,
|
||||||
|
Publisher<T> body,
|
||||||
|
ResolvableType bodyType) {
|
||||||
|
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||||
|
ServerHttpResponse response = exchange.getResponse();
|
||||||
|
return messageWriterStream(exchange)
|
||||||
|
.filter(messageWriter -> messageWriter.canWrite(bodyType, contentType, Collections
|
||||||
|
.emptyMap()))
|
||||||
|
.findFirst()
|
||||||
|
.map(CastingUtils::cast)
|
||||||
|
.map(messageWriter -> messageWriter.write(body, bodyType, contentType, response, Collections
|
||||||
|
.emptyMap()))
|
||||||
|
.orElseGet(() -> {
|
||||||
|
response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
|
||||||
|
return response.setComplete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<HttpMessageWriter<?>> messageWriterStream(ServerWebExchange exchange) {
|
||||||
|
return exchange.<Supplier<Stream<HttpMessageWriter<?>>>>getAttribute(
|
||||||
|
Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE)
|
||||||
|
.orElseThrow(() -> new IllegalStateException(
|
||||||
|
"Could not find HttpMessageWriters in ServerWebExchange"))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<ViewResolver> viewResolverStream(ServerWebExchange exchange) {
|
||||||
|
return exchange.<Supplier<Stream<ViewResolver>>>getAttribute(
|
||||||
|
Router.VIEW_RESOLVERS_ATTRIBUTE)
|
||||||
|
.orElseThrow(() -> new IllegalStateException(
|
||||||
|
"Could not find ViewResolvers in ServerWebExchange"))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final class DefaultResponse<T> implements Response<T> {
|
||||||
|
|
||||||
|
private final int statusCode;
|
||||||
|
|
||||||
|
private final HttpHeaders headers;
|
||||||
|
|
||||||
|
private final T body;
|
||||||
|
|
||||||
|
private final Function<ServerWebExchange, Mono<Void>> writingFunction;
|
||||||
|
|
||||||
|
|
||||||
|
public DefaultResponse(
|
||||||
|
int statusCode, HttpHeaders headers, T body,
|
||||||
|
Function<ServerWebExchange, Mono<Void>> writingFunction) {
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||||
|
this.body = body;
|
||||||
|
this.writingFunction = writingFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpStatus statusCode() {
|
||||||
|
return HttpStatus.valueOf(this.statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders headers() {
|
||||||
|
return this.headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T body() {
|
||||||
|
return this.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
||||||
|
writeStatusAndHeaders(exchange);
|
||||||
|
return this.writingFunction.apply(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeStatusAndHeaders(ServerWebExchange exchange) {
|
||||||
|
ServerHttpResponse response = exchange.getResponse();
|
||||||
|
response.setStatusCode(HttpStatus.valueOf(this.statusCode));
|
||||||
|
HttpHeaders responseHeaders = response.getHeaders();
|
||||||
|
|
||||||
|
if (!this.headers.isEmpty()) {
|
||||||
|
this.headers.entrySet().stream()
|
||||||
|
.filter(entry -> !responseHeaders.containsKey(entry.getKey()))
|
||||||
|
.forEach(entry -> responseHeaders
|
||||||
|
.put(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DefaultRendering implements Rendering {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final Map<String, Object> model;
|
||||||
|
|
||||||
|
|
||||||
|
public DefaultRendering(String name, Map<String, Object> model) {
|
||||||
|
this.name = name;
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> model() {
|
||||||
|
return this.model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class EmptyResponse extends AbstractResponse<Void> {
|
|
||||||
|
|
||||||
public EmptyResponse(int statusCode, HttpHeaders headers) {
|
|
||||||
super(statusCode, addContentLength(headers));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpHeaders addContentLength(HttpHeaders headers) {
|
|
||||||
if (headers.getContentLength() == -1) {
|
|
||||||
headers.setContentLength(0);
|
|
||||||
}
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void body() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
return exchange.getResponse().setComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class PublisherResponse<T, S extends Publisher<T>> extends AbstractHttpMessageWriterResponse<S> {
|
|
||||||
|
|
||||||
private final S body;
|
|
||||||
|
|
||||||
private final ResolvableType bodyType;
|
|
||||||
|
|
||||||
|
|
||||||
public PublisherResponse(int statusCode, HttpHeaders headers,
|
|
||||||
S body, Class<T> aClass) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
this.body = body;
|
|
||||||
this.bodyType = ResolvableType.forClass(aClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public S body() {
|
|
||||||
return this.body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
return writeToInternal(exchange, this.body, this.bodyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class RenderingResponse extends AbstractResponse<Rendering> {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
private final Map<String, Object> model;
|
|
||||||
|
|
||||||
private final Rendering rendering = new DefaultRendering();
|
|
||||||
|
|
||||||
public RenderingResponse(int statusCode, HttpHeaders headers, String name,
|
|
||||||
Map<String, Object> model) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
this.name = name;
|
|
||||||
this.model = Collections.unmodifiableMap(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rendering body() {
|
|
||||||
return this.rendering;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
|
||||||
Locale locale = Locale.ENGLISH; // TODO
|
|
||||||
return Flux.fromStream(viewResolverStream(exchange))
|
|
||||||
.concatMap(viewResolver -> viewResolver.resolveViewName(this.name, locale))
|
|
||||||
.next()
|
|
||||||
.otherwiseIfEmpty(Mono.error(new IllegalArgumentException("Could not resolve view with name '" + this.name +"'")))
|
|
||||||
.then(view -> view.render(this.model, contentType, exchange));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stream<ViewResolver> viewResolverStream(ServerWebExchange exchange) {
|
|
||||||
return exchange.<Supplier<Stream<ViewResolver>>>getAttribute(
|
|
||||||
Router.VIEW_RESOLVERS_ATTRIBUTE)
|
|
||||||
.orElseThrow(() -> new IllegalStateException(
|
|
||||||
"Could not find ViewResolvers in ServerWebExchange"))
|
|
||||||
.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DefaultRendering implements Rendering {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> model() {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class ResourceResponse extends AbstractResponse<Resource> {
|
|
||||||
|
|
||||||
private static final ResolvableType RESOURCE_TYPE = ResolvableType.forClass(Resource.class);
|
|
||||||
|
|
||||||
private final ResourceHttpMessageWriter messageWriter = new ResourceHttpMessageWriter();
|
|
||||||
|
|
||||||
private final Resource resource;
|
|
||||||
|
|
||||||
public ResourceResponse(int statusCode, HttpHeaders httpHeaders, Resource resource) {
|
|
||||||
super(statusCode, httpHeaders);
|
|
||||||
this.resource = resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource body() {
|
|
||||||
return this.resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
return this.messageWriter.write(Mono.just(this.resource), RESOURCE_TYPE, null,
|
|
||||||
exchange.getResponse(), Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.codec.ServerSentEvent;
|
|
||||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class ServerSentEventResponse<T extends Publisher<?>> extends AbstractResponse<T> {
|
|
||||||
|
|
||||||
private static final boolean jackson2Present =
|
|
||||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
|
||||||
DefaultConfiguration.class.getClassLoader()) &&
|
|
||||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
|
|
||||||
DefaultConfiguration.class.getClassLoader());
|
|
||||||
|
|
||||||
private static final ResolvableType SERVER_SIDE_EVENT_TYPE = ResolvableType.forClass(ServerSentEvent.class);
|
|
||||||
|
|
||||||
private final ServerSentEventHttpMessageWriter messageWriter;
|
|
||||||
|
|
||||||
private final T eventsPublisher;
|
|
||||||
|
|
||||||
private final ResolvableType eventType;
|
|
||||||
|
|
||||||
|
|
||||||
private ServerSentEventResponse(int statusCode, HttpHeaders headers, T eventsPublisher, ResolvableType eventType) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
this.eventsPublisher = eventsPublisher;
|
|
||||||
this.eventType = eventType;
|
|
||||||
this.messageWriter =
|
|
||||||
jackson2Present ? new ServerSentEventHttpMessageWriter(Collections.singletonList(new Jackson2JsonEncoder())) :
|
|
||||||
new ServerSentEventHttpMessageWriter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, S extends Publisher<T>> ServerSentEventResponse<S> fromPublisher(int statusCode, HttpHeaders headers, S eventsPublisher, Class<? extends T> eventType) {
|
|
||||||
return new ServerSentEventResponse<S>(statusCode, headers, eventsPublisher, ResolvableType.forClass(eventType));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, S extends Publisher<ServerSentEvent<T>>> ServerSentEventResponse<S> fromSseEvents(int statusCode, HttpHeaders headers, S eventsPublisher) {
|
|
||||||
return new ServerSentEventResponse<S>(statusCode, headers, eventsPublisher, SERVER_SIDE_EVENT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T body() {
|
|
||||||
return this.eventsPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
return this.messageWriter.write(this.eventsPublisher, this.eventType, null,
|
|
||||||
exchange.getResponse(), Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
class VoidPublisherResponse<T extends Publisher<Void>> extends AbstractResponse<T> {
|
|
||||||
|
|
||||||
private final T voidPublisher;
|
|
||||||
|
|
||||||
public VoidPublisherResponse(int statusCode, HttpHeaders headers,
|
|
||||||
T voidPublisher) {
|
|
||||||
super(statusCode, headers);
|
|
||||||
this.voidPublisher = voidPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T body() {
|
|
||||||
return this.voidPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> writeTo(ServerWebExchange exchange) {
|
|
||||||
writeStatusAndHeaders(exchange);
|
|
||||||
return Flux.from(this.voidPublisher)
|
|
||||||
.then(exchange.getResponse().setComplete());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.springframework.core.codec.CharSequenceEncoder;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
|
||||||
import org.springframework.web.server.session.MockWebSessionManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class BodyResponseTests {
|
|
||||||
|
|
||||||
private final String body = "foo";
|
|
||||||
|
|
||||||
private final BodyResponse<String> publisherResponse =
|
|
||||||
new BodyResponse<>(200, new HttpHeaders(), body);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
assertEquals(body, publisherResponse.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
ServerWebExchange exchange = new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
|
||||||
Set<HttpMessageWriter<?>> messageWriters = Collections.singleton(new EncoderHttpMessageWriter<CharSequence>(new CharSequenceEncoder()));
|
|
||||||
exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE,
|
|
||||||
(Supplier<Stream<HttpMessageWriter<?>>>) messageWriters::stream);
|
|
||||||
|
|
||||||
|
|
||||||
publisherResponse.writeTo(exchange).block();
|
|
||||||
assertNotNull(response.getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -19,16 +19,39 @@ package org.springframework.web.reactive.function;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.reactivestreams.Publisher;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import org.springframework.core.codec.CharSequenceEncoder;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.CacheControl;
|
import org.springframework.http.CacheControl;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.HttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.ServerSentEvent;
|
||||||
|
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||||
|
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||||
|
import org.springframework.web.reactive.result.view.View;
|
||||||
|
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||||
|
import org.springframework.web.server.session.MockWebSessionManager;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
@@ -142,6 +165,160 @@ public class DefaultResponseBuilderTests {
|
|||||||
assertEquals(Collections.singletonList("foo"), result.headers().getVary());
|
assertEquals(Collections.singletonList("foo"), result.headers().getVary());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void statusCode() throws Exception {
|
||||||
|
HttpStatus statusCode = HttpStatus.ACCEPTED;
|
||||||
|
Response<Void> result = Response.status(statusCode).build();
|
||||||
|
assertSame(statusCode, result.statusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headers() throws Exception {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
Response<Void> result = Response.ok().headers(headers).build();
|
||||||
|
assertEquals(headers, result.headers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void build() throws Exception {
|
||||||
|
Response<Void> result = Response.status(201).header("MyKey", "MyValue").build();
|
||||||
|
|
||||||
|
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
when(exchange.getResponse()).thenReturn(response);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertEquals(201, response.getStatusCode().value());
|
||||||
|
assertEquals("MyValue", response.getHeaders().getFirst("MyKey"));
|
||||||
|
assertNull(response.getBody());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void buildVoidPublisher() throws Exception {
|
||||||
|
Mono<Void> mono = Mono.empty();
|
||||||
|
Response<Mono<Void>> result = Response.ok().build(mono);
|
||||||
|
|
||||||
|
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
when(exchange.getResponse()).thenReturn(response);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertNull(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void body() throws Exception {
|
||||||
|
String body = "foo";
|
||||||
|
Response<String> result = Response.ok().body(body);
|
||||||
|
assertEquals(body, result.body());
|
||||||
|
|
||||||
|
MockServerHttpRequest request =
|
||||||
|
new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
ServerWebExchange exchange =
|
||||||
|
new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
||||||
|
Set<HttpMessageWriter<?>>
|
||||||
|
messageWriters = Collections
|
||||||
|
.singleton(new EncoderHttpMessageWriter<CharSequence>(new CharSequenceEncoder()));
|
||||||
|
exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE,
|
||||||
|
(Supplier<Stream<HttpMessageWriter<?>>>) messageWriters::stream);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bodyNotAcceptable() throws Exception {
|
||||||
|
String body = "foo";
|
||||||
|
Response<String> result = Response.ok().contentType(MediaType.APPLICATION_JSON).body(body);
|
||||||
|
assertEquals(body, result.body());
|
||||||
|
|
||||||
|
MockServerHttpRequest request =
|
||||||
|
new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
ServerWebExchange exchange =
|
||||||
|
new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
||||||
|
Set<HttpMessageWriter<?>>
|
||||||
|
messageWriters = Collections
|
||||||
|
.singleton(new EncoderHttpMessageWriter<CharSequence>(new CharSequenceEncoder()));
|
||||||
|
exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE,
|
||||||
|
(Supplier<Stream<HttpMessageWriter<?>>>) messageWriters::stream);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertEquals(HttpStatus.NOT_ACCEPTABLE, response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stream() throws Exception {
|
||||||
|
Publisher<String> publisher = Flux.just("foo", "bar");
|
||||||
|
Response<Publisher<String>> result = Response.ok().stream(publisher, String.class);
|
||||||
|
|
||||||
|
MockServerHttpRequest request =
|
||||||
|
new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
ServerWebExchange exchange =
|
||||||
|
new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
||||||
|
Set<HttpMessageWriter<?>> messageWriters = Collections
|
||||||
|
.singleton(new EncoderHttpMessageWriter<CharSequence>(new CharSequenceEncoder()));
|
||||||
|
exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE,
|
||||||
|
(Supplier<Stream<HttpMessageWriter<?>>>) messageWriters::stream);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resource() throws Exception {
|
||||||
|
Resource resource = new ClassPathResource("response.txt", DefaultResponseBuilderTests.class);
|
||||||
|
Response<Resource> result = Response.ok().resource(resource);
|
||||||
|
|
||||||
|
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
when(exchange.getResponse()).thenReturn(response);
|
||||||
|
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertNotNull(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sse() throws Exception {
|
||||||
|
ServerSentEvent<String> sse = ServerSentEvent.<String>builder().data("42").build();
|
||||||
|
Mono<ServerSentEvent<String>> body = Mono.just(sse);
|
||||||
|
Response<Mono<ServerSentEvent<String>>> result = Response.ok().sse(body);
|
||||||
|
|
||||||
|
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
when(exchange.getResponse()).thenReturn(response);
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
assertNotNull(response.getBodyWithFlush());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void render() throws Exception {
|
||||||
|
Map<String, Object> model = Collections.singletonMap("foo", "bar");
|
||||||
|
Response<Rendering> result = Response.ok().render("view", model);
|
||||||
|
|
||||||
|
assertEquals("view", result.body().name());
|
||||||
|
assertEquals(model, result.body().model());
|
||||||
|
|
||||||
|
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, URI.create("http://localhost"));
|
||||||
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
ServerWebExchange exchange = new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
||||||
|
ViewResolver viewResolver = mock(ViewResolver.class);
|
||||||
|
View view = mock(View.class);
|
||||||
|
when(viewResolver.resolveViewName("view", Locale.ENGLISH)).thenReturn(Mono.just(view));
|
||||||
|
when(view.render(model, null, exchange)).thenReturn(Mono.empty());
|
||||||
|
exchange.getAttributes().put(Router.VIEW_RESOLVERS_ATTRIBUTE,
|
||||||
|
(Supplier<Stream<ViewResolver>>) () -> Collections
|
||||||
|
.singleton(viewResolver).stream());
|
||||||
|
|
||||||
|
|
||||||
|
result.writeTo(exchange).block();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void renderObjectArray() throws Exception {
|
public void renderObjectArray() throws Exception {
|
||||||
Response<Rendering> result =
|
Response<Rendering> result =
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class EmptyResponseTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void statusCode() throws Exception {
|
|
||||||
HttpStatus statusCode = HttpStatus.ACCEPTED;
|
|
||||||
EmptyResponse emptyResponse = new EmptyResponse(statusCode.value(), new HttpHeaders());
|
|
||||||
assertSame(statusCode, emptyResponse.statusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headers() throws Exception {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
EmptyResponse emptyResponse = new EmptyResponse(200, headers);
|
|
||||||
assertEquals(headers, emptyResponse.headers());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
EmptyResponse emptyResponse = new EmptyResponse(200, new HttpHeaders());
|
|
||||||
assertNull(emptyResponse.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.add("MyKey", "MyValue");
|
|
||||||
EmptyResponse emptyResponse = new EmptyResponse(201, headers);
|
|
||||||
|
|
||||||
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
when(exchange.getResponse()).thenReturn(response);
|
|
||||||
|
|
||||||
|
|
||||||
emptyResponse.writeTo(exchange).block();
|
|
||||||
assertEquals(201, response.getStatusCode().value());
|
|
||||||
assertEquals("MyValue", response.getHeaders().getFirst("MyKey"));
|
|
||||||
assertNull(response.getBody());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
import org.springframework.core.codec.CharSequenceEncoder;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
|
||||||
import org.springframework.web.server.session.MockWebSessionManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class PublisherResponseTests {
|
|
||||||
|
|
||||||
private final Publisher<String> publisher = Flux.just("foo", "bar");
|
|
||||||
|
|
||||||
private final PublisherResponse<String, ? extends Publisher<String>> publisherResponse =
|
|
||||||
new PublisherResponse<>(200, new HttpHeaders(), publisher, String.class);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
assertEquals(publisher, publisherResponse.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
ServerWebExchange exchange = new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
|
||||||
Set<HttpMessageWriter<?>> messageWriters = Collections.singleton(new EncoderHttpMessageWriter<CharSequence>(new CharSequenceEncoder()));
|
|
||||||
exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE,
|
|
||||||
(Supplier<Stream<HttpMessageWriter<?>>>) messageWriters::stream);
|
|
||||||
|
|
||||||
|
|
||||||
publisherResponse.writeTo(exchange).block();
|
|
||||||
assertNotNull(response.getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.web.reactive.result.view.View;
|
|
||||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
|
||||||
import org.springframework.web.server.session.MockWebSessionManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class RenderingResponseTests {
|
|
||||||
|
|
||||||
private final Map<String, Object> model = Collections.singletonMap("foo", "bar");
|
|
||||||
|
|
||||||
private final RenderingResponse renderingResponse = new RenderingResponse(200, new HttpHeaders(), "view",
|
|
||||||
model);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
assertEquals("view", renderingResponse.body().name());
|
|
||||||
assertEquals(model, renderingResponse.body().model());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, URI.create("http://localhost"));
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
ServerWebExchange exchange = new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
|
||||||
ViewResolver viewResolver = mock(ViewResolver.class);
|
|
||||||
View view = mock(View.class);
|
|
||||||
when(viewResolver.resolveViewName("view", Locale.ENGLISH)).thenReturn(Mono.just(view));
|
|
||||||
when(view.render(model, null, exchange)).thenReturn(Mono.empty());
|
|
||||||
exchange.getAttributes().put(Router.VIEW_RESOLVERS_ATTRIBUTE,
|
|
||||||
(Supplier<Stream<ViewResolver>>) () -> Collections
|
|
||||||
.singleton(viewResolver).stream());
|
|
||||||
|
|
||||||
|
|
||||||
renderingResponse.writeTo(exchange).block();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class ResourceResponseTests {
|
|
||||||
|
|
||||||
private final Resource resource = new ClassPathResource("response.txt", ResourceResponseTests.class);
|
|
||||||
|
|
||||||
private final ResourceResponse resourceResponse =
|
|
||||||
new ResourceResponse(200, new HttpHeaders(), resource);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
assertEquals(resource, resourceResponse.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
when(exchange.getResponse()).thenReturn(response);
|
|
||||||
|
|
||||||
|
|
||||||
resourceResponse.writeTo(exchange).block();
|
|
||||||
assertNotNull(response.getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2016 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.reactive.function;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.codec.ServerSentEvent;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
|
||||||
import org.springframework.tests.TestSubscriber;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
|
||||||
import org.springframework.web.server.session.MockWebSessionManager;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class ServerSentEventResponseTests {
|
|
||||||
|
|
||||||
private final ServerSentEvent<String> sse =
|
|
||||||
ServerSentEvent.<String>builder().data("42").build();
|
|
||||||
|
|
||||||
private final Publisher<ServerSentEvent<String>> body = Mono.just(sse);
|
|
||||||
|
|
||||||
private final ServerSentEventResponse<Publisher<ServerSentEvent<String>>> sseResponse =
|
|
||||||
ServerSentEventResponse.fromSseEvents(200, new HttpHeaders(), body);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void body() throws Exception {
|
|
||||||
assertEquals(body, sseResponse.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void writeTo() throws Exception {
|
|
||||||
MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
|
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
|
||||||
ServerWebExchange exchange = new DefaultServerWebExchange(request, response, new MockWebSessionManager());
|
|
||||||
|
|
||||||
sseResponse.writeTo(exchange);
|
|
||||||
Publisher<Publisher<DataBuffer>> result = response.getBodyWithFlush();
|
|
||||||
TestSubscriber.subscribe(result).
|
|
||||||
assertNoError().
|
|
||||||
assertValuesWith(publisher -> {
|
|
||||||
TestSubscriber.subscribe(publisher).assertNoError();
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user