diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractHttpMessageWriterResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractHttpMessageWriterResponse.java deleted file mode 100644 index 02c86b73b0..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractHttpMessageWriterResponse.java +++ /dev/null @@ -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 extends AbstractResponse { - - protected AbstractHttpMessageWriterResponse(int statusCode, HttpHeaders headers) { - super(statusCode, headers); - } - - protected Mono writeToInternal(ServerWebExchange exchange, - Publisher 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> messageWriterStream(ServerWebExchange exchange) { - return exchange.>>>getAttribute(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE) - .orElseThrow(() -> new IllegalStateException("Could not find HttpMessageWriters in ServerWebExchange")) - .get(); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractResponse.java deleted file mode 100644 index cf2bb9e9bb..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/AbstractResponse.java +++ /dev/null @@ -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 implements Response { - - 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())); - } - } -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/BodyResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/BodyResponse.java deleted file mode 100644 index 25c1f2ea6f..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/BodyResponse.java +++ /dev/null @@ -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 extends AbstractHttpMessageWriterResponse { - - 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 writeTo(ServerWebExchange exchange) { - return writeToInternal(exchange, Mono.just(this.body), ResolvableType.forInstance(this.body)); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponseBuilder.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponseBuilder.java index d8d95f0da2..8a08e1de12 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponseBuilder.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponseBuilder.java @@ -132,47 +132,45 @@ class DefaultResponseBuilder implements Response.BodyBuilder { @Override public Response build() { - return new EmptyResponse(this.statusCode, this.headers); + return DefaultResponses.empty(this.statusCode, this.headers); } @Override public > Response build(T voidPublisher) { 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 public Response body(T body) { 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 public > Response stream(S publisher, Class elementClass) { Assert.notNull(publisher, "'publisher' 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 public Response resource(Resource resource) { 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 public >> Response sse(S eventsPublisher) { Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null"); - return ServerSentEventResponse - .fromSseEvents(this.statusCode, this.headers, eventsPublisher); + return DefaultResponses.sse(this.statusCode, this.headers, eventsPublisher); } @Override public > Response sse(S eventsPublisher, Class eventClass) { Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null"); Assert.notNull(eventClass, "'eventClass' must not be null"); - return ServerSentEventResponse - .fromPublisher(this.statusCode, this.headers, eventsPublisher, eventClass); + return DefaultResponses.sse(this.statusCode, this.headers, eventsPublisher, eventClass); } @Override @@ -180,7 +178,11 @@ class DefaultResponseBuilder implements Response.BodyBuilder { Map modelMap = Arrays.stream(modelAttributes) .filter(o -> !isEmptyCollection(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 @@ -190,11 +192,7 @@ class DefaultResponseBuilder implements Response.BodyBuilder { if (model != null) { modelMap.putAll(model); } - return new RenderingResponse(this.statusCode, this.headers, name, modelMap); - } - - private static boolean isEmptyCollection(Object o) { - return o instanceof Collection && ((Collection) o).isEmpty(); + return DefaultResponses.render(this.statusCode, this.headers, name, modelMap); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponses.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponses.java new file mode 100644 index 0000000000..c73203b880 --- /dev/null +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultResponses.java @@ -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 empty(int statusCode, HttpHeaders headers) { + return new DefaultResponse<>(statusCode, headers, null, + exchange -> exchange.getResponse().setComplete() + ); + } + + public static > Response empty(int statusCode, HttpHeaders headers, + T voidPublisher) { + return new DefaultResponse(statusCode, headers, voidPublisher, + exchange -> Flux.from(voidPublisher) + .then(exchange.getResponse().setComplete())); + } + + public static Response 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 Response body(int statusCode, HttpHeaders headers, T body) { + return new DefaultResponse(statusCode, headers, body, + exchange -> writeWithMessageWriters(exchange, Mono.just(body), + ResolvableType.forInstance(body))); + } + + public static , T> Response stream(int statusCode, + HttpHeaders headers, S publisher, + Class elementClass) { + return new DefaultResponse(statusCode, headers, publisher, + exchange -> writeWithMessageWriters(exchange, publisher, + ResolvableType.forClass(elementClass))); + } + + public static >> Response sse(int statusCode, + HttpHeaders headers, S eventsPublisher) { + return new DefaultResponse(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 , T> Response sse(int statusCode, HttpHeaders headers, + S eventsPublisher, + Class eventClass) { + return new DefaultResponse(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 render(int statusCode, HttpHeaders headers, String name, + Map 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 Mono writeWithMessageWriters(ServerWebExchange exchange, + Publisher 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> messageWriterStream(ServerWebExchange exchange) { + return exchange.>>>getAttribute( + Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE) + .orElseThrow(() -> new IllegalStateException( + "Could not find HttpMessageWriters in ServerWebExchange")) + .get(); + } + + private static Stream viewResolverStream(ServerWebExchange exchange) { + return exchange.>>getAttribute( + Router.VIEW_RESOLVERS_ATTRIBUTE) + .orElseThrow(() -> new IllegalStateException( + "Could not find ViewResolvers in ServerWebExchange")) + .get(); + } + + + private static final class DefaultResponse implements Response { + + private final int statusCode; + + private final HttpHeaders headers; + + private final T body; + + private final Function> writingFunction; + + + public DefaultResponse( + int statusCode, HttpHeaders headers, T body, + Function> 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 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 model; + + + public DefaultRendering(String name, Map model) { + this.name = name; + this.model = model; + } + + @Override + public String name() { + return this.name; + } + + @Override + public Map model() { + return this.model; + } + } +} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/EmptyResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/EmptyResponse.java deleted file mode 100644 index e684eeea8b..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/EmptyResponse.java +++ /dev/null @@ -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 { - - 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 writeTo(ServerWebExchange exchange) { - writeStatusAndHeaders(exchange); - return exchange.getResponse().setComplete(); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/PublisherResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/PublisherResponse.java deleted file mode 100644 index aadabb52b4..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/PublisherResponse.java +++ /dev/null @@ -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> extends AbstractHttpMessageWriterResponse { - - private final S body; - - private final ResolvableType bodyType; - - - public PublisherResponse(int statusCode, HttpHeaders headers, - S body, Class aClass) { - super(statusCode, headers); - this.body = body; - this.bodyType = ResolvableType.forClass(aClass); - } - - @Override - public S body() { - return this.body; - } - - @Override - public Mono writeTo(ServerWebExchange exchange) { - return writeToInternal(exchange, this.body, this.bodyType); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RenderingResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RenderingResponse.java deleted file mode 100644 index bc0183f9a9..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RenderingResponse.java +++ /dev/null @@ -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 { - - private final String name; - - private final Map model; - - private final Rendering rendering = new DefaultRendering(); - - public RenderingResponse(int statusCode, HttpHeaders headers, String name, - Map model) { - super(statusCode, headers); - this.name = name; - this.model = Collections.unmodifiableMap(model); - } - - @Override - public Rendering body() { - return this.rendering; - } - - @Override - public Mono 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 viewResolverStream(ServerWebExchange exchange) { - return exchange.>>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 model() { - return model; - } - } -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ResourceResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ResourceResponse.java deleted file mode 100644 index 383d4e6e26..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ResourceResponse.java +++ /dev/null @@ -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 { - - 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 writeTo(ServerWebExchange exchange) { - writeStatusAndHeaders(exchange); - return this.messageWriter.write(Mono.just(this.resource), RESOURCE_TYPE, null, - exchange.getResponse(), Collections.emptyMap()); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ServerSentEventResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ServerSentEventResponse.java deleted file mode 100644 index 66a8dc7906..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/ServerSentEventResponse.java +++ /dev/null @@ -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> extends AbstractResponse { - - 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 > ServerSentEventResponse fromPublisher(int statusCode, HttpHeaders headers, S eventsPublisher, Class eventType) { - return new ServerSentEventResponse(statusCode, headers, eventsPublisher, ResolvableType.forClass(eventType)); - } - - public static >> ServerSentEventResponse fromSseEvents(int statusCode, HttpHeaders headers, S eventsPublisher) { - return new ServerSentEventResponse(statusCode, headers, eventsPublisher, SERVER_SIDE_EVENT_TYPE); - } - - @Override - public T body() { - return this.eventsPublisher; - } - - @Override - public Mono writeTo(ServerWebExchange exchange) { - writeStatusAndHeaders(exchange); - return this.messageWriter.write(this.eventsPublisher, this.eventType, null, - exchange.getResponse(), Collections.emptyMap()); - } - -} diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/VoidPublisherResponse.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/VoidPublisherResponse.java deleted file mode 100644 index ec60199358..0000000000 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/function/VoidPublisherResponse.java +++ /dev/null @@ -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> extends AbstractResponse { - - 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 writeTo(ServerWebExchange exchange) { - writeStatusAndHeaders(exchange); - return Flux.from(this.voidPublisher) - .then(exchange.getResponse().setComplete()); - } -} diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/BodyResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/BodyResponseTests.java deleted file mode 100644 index c305b0b788..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/BodyResponseTests.java +++ /dev/null @@ -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 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> messageWriters = Collections.singleton(new EncoderHttpMessageWriter(new CharSequenceEncoder())); - exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE, - (Supplier>>) messageWriters::stream); - - - publisherResponse.writeTo(exchange).block(); - assertNotNull(response.getBody()); - } - -} \ No newline at end of file diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java index 9035ce4aa7..01acfccb94 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/DefaultResponseBuilderTests.java @@ -19,16 +19,39 @@ package org.springframework.web.reactive.function; import java.net.URI; import java.time.ZonedDateTime; import java.util.Collections; +import java.util.Locale; import java.util.Map; +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 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.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; 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 @@ -142,6 +165,160 @@ public class DefaultResponseBuilderTests { assertEquals(Collections.singletonList("foo"), result.headers().getVary()); } + @Test + public void statusCode() throws Exception { + HttpStatus statusCode = HttpStatus.ACCEPTED; + Response result = Response.status(statusCode).build(); + assertSame(statusCode, result.statusCode()); + } + + @Test + public void headers() throws Exception { + HttpHeaders headers = new HttpHeaders(); + Response result = Response.ok().headers(headers).build(); + assertEquals(headers, result.headers()); + } + + @Test + public void build() throws Exception { + Response 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 mono = Mono.empty(); + Response> 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 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> + messageWriters = Collections + .singleton(new EncoderHttpMessageWriter(new CharSequenceEncoder())); + exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE, + (Supplier>>) messageWriters::stream); + + result.writeTo(exchange).block(); + assertNotNull(response.getBody()); + } + + @Test + public void bodyNotAcceptable() throws Exception { + String body = "foo"; + Response 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> + messageWriters = Collections + .singleton(new EncoderHttpMessageWriter(new CharSequenceEncoder())); + exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE, + (Supplier>>) messageWriters::stream); + + result.writeTo(exchange).block(); + assertEquals(HttpStatus.NOT_ACCEPTABLE, response.getStatusCode()); + } + + @Test + public void stream() throws Exception { + Publisher publisher = Flux.just("foo", "bar"); + Response> 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> messageWriters = Collections + .singleton(new EncoderHttpMessageWriter(new CharSequenceEncoder())); + exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE, + (Supplier>>) messageWriters::stream); + + result.writeTo(exchange).block(); + assertNotNull(response.getBody()); + } + + @Test + public void resource() throws Exception { + Resource resource = new ClassPathResource("response.txt", DefaultResponseBuilderTests.class); + Response 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 sse = ServerSentEvent.builder().data("42").build(); + Mono> body = Mono.just(sse); + Response>> 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 model = Collections.singletonMap("foo", "bar"); + Response 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>) () -> Collections + .singleton(viewResolver).stream()); + + + result.writeTo(exchange).block(); + } + @Test public void renderObjectArray() throws Exception { Response result = diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/EmptyResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/EmptyResponseTests.java deleted file mode 100644 index d43c0a905b..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/EmptyResponseTests.java +++ /dev/null @@ -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()); - } -} \ No newline at end of file diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherResponseTests.java deleted file mode 100644 index 65868a2ac1..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/PublisherResponseTests.java +++ /dev/null @@ -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 publisher = Flux.just("foo", "bar"); - - private final PublisherResponse> 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> messageWriters = Collections.singleton(new EncoderHttpMessageWriter(new CharSequenceEncoder())); - exchange.getAttributes().put(Router.HTTP_MESSAGE_WRITERS_ATTRIBUTE, - (Supplier>>) messageWriters::stream); - - - publisherResponse.writeTo(exchange).block(); - assertNotNull(response.getBody()); - } - -} \ No newline at end of file diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/RenderingResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/RenderingResponseTests.java deleted file mode 100644 index d450c5b2aa..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/RenderingResponseTests.java +++ /dev/null @@ -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 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>) () -> Collections - .singleton(viewResolver).stream()); - - - renderingResponse.writeTo(exchange).block(); - } - - -} \ No newline at end of file diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ResourceResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ResourceResponseTests.java deleted file mode 100644 index ae12aa0eea..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ResourceResponseTests.java +++ /dev/null @@ -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()); - } - -} \ No newline at end of file diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ServerSentEventResponseTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ServerSentEventResponseTests.java deleted file mode 100644 index 9b621bde4a..0000000000 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/function/ServerSentEventResponseTests.java +++ /dev/null @@ -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 sse = - ServerSentEvent.builder().data("42").build(); - - private final Publisher> body = Mono.just(sse); - - private final ServerSentEventResponse>> 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> result = response.getBodyWithFlush(); - TestSubscriber.subscribe(result). - assertNoError(). - assertValuesWith(publisher -> { - TestSubscriber.subscribe(publisher).assertNoError(); - - }); - } - -} \ No newline at end of file