Browse Source

Functional response builders allow for non-standard HTTP status codes

Issue: SPR-16366
pull/1624/merge
Juergen Hoeller 7 years ago
parent
commit
9623cdec48
  1. 5
      spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java
  2. 30
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java
  3. 49
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseBuilder.java
  4. 81
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java
  5. 13
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java
  6. 21
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RenderingResponse.java
  7. 19
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java

5
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -43,6 +43,7 @@ import org.springframework.util.MultiValueMap; @@ -43,6 +43,7 @@ import org.springframework.util.MultiValueMap;
* Base class for {@link ServerHttpResponse} implementations.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 5.0
*/
@ -112,7 +113,7 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse { @@ -112,7 +113,7 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
* @param statusCode the HTTP status as an integer value
* @since 5.0.1
*/
public void setStatusCodeValue(Integer statusCode) {
public void setStatusCodeValue(@Nullable Integer statusCode) {
this.statusCode = statusCode;
}

30
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -50,6 +50,7 @@ import org.springframework.web.server.ServerWebExchange; @@ -50,6 +50,7 @@ import org.springframework.web.server.ServerWebExchange;
* Default {@link EntityResponse.Builder} implementation.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
@ -58,7 +59,7 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -58,7 +59,7 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
private final BodyInserter<T, ? super ServerHttpResponse> inserter;
private HttpStatus status = HttpStatus.OK;
private int status = HttpStatus.OK.value();
private final HttpHeaders headers = new HttpHeaders();
@ -75,22 +76,27 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -75,22 +76,27 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
@Override
public EntityResponse.Builder<T> status(HttpStatus status) {
Assert.notNull(status, "'status' must not be null");
Assert.notNull(status, "HttpStatus must not be null");
this.status = status.value();
return this;
}
@Override
public EntityResponse.Builder<T> status(int status) {
this.status = status;
return this;
}
@Override
public EntityResponse.Builder<T> cookie(ResponseCookie cookie) {
Assert.notNull(cookie, "'cookie' must not be null");
Assert.notNull(cookie, "ResponseCookie must not be null");
this.cookies.add(cookie.getName(), cookie);
return this;
}
@Override
public EntityResponse.Builder<T> cookies(
Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer) {
Assert.notNull(cookiesConsumer, "'cookiesConsumer' must not be null");
public EntityResponse.Builder<T> cookies(Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer) {
Assert.notNull(cookiesConsumer, "Consumer must not be null");
cookiesConsumer.accept(this.cookies);
return this;
}
@ -182,8 +188,8 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -182,8 +188,8 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
@Override
public Mono<EntityResponse<T>> build() {
return Mono.just(new DefaultEntityResponse<T>(this.status, this.headers, this.cookies,
this.entity, this.inserter, this.hints));
return Mono.just(new DefaultEntityResponse<T>(
this.status, this.headers, this.cookies, this.entity, this.inserter, this.hints));
}
@ -197,8 +203,7 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -197,8 +203,7 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
private final Map<String, Object> hints;
public DefaultEntityResponse(HttpStatus statusCode, HttpHeaders headers,
public DefaultEntityResponse(int statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies, T entity,
BodyInserter<T, ? super ServerHttpResponse> inserter, Map<String, Object> hints) {
@ -208,7 +213,6 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -208,7 +213,6 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
this.hints = hints;
}
@Override
public T entity() {
return this.entity;
@ -228,12 +232,10 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> { @@ -228,12 +232,10 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
public List<HttpMessageWriter<?>> messageWriters() {
return context.messageWriters();
}
@Override
public Optional<ServerHttpRequest> serverRequest() {
return Optional.of(exchange.getRequest());
}
@Override
public Map<String, Object> hints() {
return hints;

49
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseBuilder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -47,13 +47,14 @@ import org.springframework.web.server.ServerWebExchange; @@ -47,13 +47,14 @@ import org.springframework.web.server.ServerWebExchange;
* Default {@link RenderingResponse.Builder} implementation.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
private final String name;
private HttpStatus status = HttpStatus.OK;
private int status = HttpStatus.OK.value();
private final HttpHeaders headers = new HttpHeaders();
@ -62,6 +63,14 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -62,6 +63,14 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
private final Map<String, Object> model = new LinkedHashMap<>();
public DefaultRenderingResponseBuilder(RenderingResponse other) {
this.name = other.name();
this.status = (other instanceof DefaultRenderingResponse ?
((DefaultRenderingResponse) other).statusCode : other.statusCode().value());
this.headers.putAll(other.headers());
this.model.putAll(other.model());
}
public DefaultRenderingResponseBuilder(String name) {
this.name = name;
}
@ -69,28 +78,34 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -69,28 +78,34 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
@Override
public RenderingResponse.Builder status(HttpStatus status) {
Assert.notNull(status, "'status' must not be null");
Assert.notNull(status, "HttpStatus must not be null");
this.status = status.value();
return this;
}
@Override
public RenderingResponse.Builder status(int status) {
this.status = status;
return this;
}
@Override
public RenderingResponse.Builder cookie(ResponseCookie cookie) {
Assert.notNull(cookie, "'cookie' must not be null");
Assert.notNull(cookie, "ResponseCookie must not be null");
this.cookies.add(cookie.getName(), cookie);
return this;
}
@Override
public RenderingResponse.Builder cookies(Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer) {
Assert.notNull(cookiesConsumer, "'cookiesConsumer' must not be null");
Assert.notNull(cookiesConsumer, "Consumer must not be null");
cookiesConsumer.accept(this.cookies);
return this;
}
@Override
public RenderingResponse.Builder modelAttribute(Object attribute) {
Assert.notNull(attribute, "'value' must not be null");
Assert.notNull(attribute, "Attribute must not be null");
if (attribute instanceof Collection && ((Collection<?>) attribute).isEmpty()) {
return this;
}
@ -99,7 +114,7 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -99,7 +114,7 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
@Override
public RenderingResponse.Builder modelAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "'name' must not be null");
Assert.notNull(name, "Name must not be null");
this.model.put(name, value);
return this;
}
@ -138,32 +153,26 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -138,32 +153,26 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
@Override
public Mono<RenderingResponse> build() {
return Mono.just(new DefaultRenderingResponse(this.status, this.headers, this.cookies,
this.name, this.model));
return Mono.just(
new DefaultRenderingResponse(this.status, this.headers, this.cookies, this.name, this.model));
}
private final static class DefaultRenderingResponse
extends DefaultServerResponseBuilder.AbstractServerResponse
private static final class DefaultRenderingResponse extends DefaultServerResponseBuilder.AbstractServerResponse
implements RenderingResponse {
private final String name;
private final Map<String, Object> model;
public DefaultRenderingResponse(HttpStatus statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies,
String name, Map<String, Object> model) {
public DefaultRenderingResponse(int statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies, String name, Map<String, Object> model) {
super(statusCode, headers, cookies);
this.name = name;
this.model = unmodifiableCopy(model);
this.model = Collections.unmodifiableMap(new LinkedHashMap<>(model));
}
private static <K, V> Map<K, V> unmodifiableCopy(Map<? extends K, ? extends V> m) {
return Collections.unmodifiableMap(new LinkedHashMap<>(m));
}
@Override
public String name() {
return this.name;

81
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -39,6 +39,7 @@ import org.springframework.http.HttpStatus; @@ -39,6 +39,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.Assert;
@ -53,11 +54,12 @@ import org.springframework.web.server.ServerWebExchange; @@ -53,11 +54,12 @@ import org.springframework.web.server.ServerWebExchange;
* Default {@link ServerResponse.BodyBuilder} implementation.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
private final HttpStatus statusCode;
private final int statusCode;
private final HttpHeaders headers = new HttpHeaders();
@ -66,7 +68,17 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -66,7 +68,17 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
private final Map<String, Object> hints = new HashMap<>();
public DefaultServerResponseBuilder(ServerResponse other) {
this.statusCode = (other instanceof AbstractServerResponse ?
((AbstractServerResponse) other).statusCode : other.statusCode().value());
this.headers.addAll(other.headers());
}
public DefaultServerResponseBuilder(HttpStatus statusCode) {
this.statusCode = statusCode.value();
}
public DefaultServerResponseBuilder(int statusCode) {
this.statusCode = statusCode;
}
@ -81,22 +93,21 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -81,22 +93,21 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public ServerResponse.BodyBuilder headers(Consumer<HttpHeaders> headersConsumer) {
Assert.notNull(headersConsumer, "'headersConsumer' must not be null");
Assert.notNull(headersConsumer, "Consumer must not be null");
headersConsumer.accept(this.headers);
return this;
}
@Override
public ServerResponse.BodyBuilder cookie(ResponseCookie cookie) {
Assert.notNull(cookie, "'cookie' must not be null");
Assert.notNull(cookie, "ResponseCookie must not be null");
this.cookies.add(cookie.getName(), cookie);
return this;
}
@Override
public ServerResponse.BodyBuilder cookies(
Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer) {
Assert.notNull(cookiesConsumer, "'cookiesConsumer' must not be null");
public ServerResponse.BodyBuilder cookies(Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer) {
Assert.notNull(cookiesConsumer, "Consumer must not be null");
cookiesConsumer.accept(this.cookies);
return this;
}
@ -177,7 +188,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -177,7 +188,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public Mono<ServerResponse> build(Publisher<Void> voidPublisher) {
Assert.notNull(voidPublisher, "'voidPublisher' must not be null");
Assert.notNull(voidPublisher, "Publisher must not be null");
return build((exchange, handlerStrategies) ->
Mono.from(voidPublisher).then(exchange.getResponse().setComplete()));
}
@ -186,15 +197,15 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -186,15 +197,15 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
public Mono<ServerResponse> build(
BiFunction<ServerWebExchange, ServerResponse.Context, Mono<Void>> writeFunction) {
Assert.notNull(writeFunction, "'writeFunction' must not be null");
return Mono.just(new WriterFunctionServerResponse(this.statusCode, this.headers,
this.cookies, writeFunction));
Assert.notNull(writeFunction, "BiFunction must not be null");
return Mono.just(
new WriterFunctionServerResponse(this.statusCode, this.headers, this.cookies, writeFunction));
}
@Override
public <T, P extends Publisher<T>> Mono<ServerResponse> body(P publisher, Class<T> elementClass) {
Assert.notNull(publisher, "'publisher' must not be null");
Assert.notNull(elementClass, "'elementClass' must not be null");
Assert.notNull(publisher, "Publisher must not be null");
Assert.notNull(elementClass, "Element Class must not be null");
return new DefaultEntityResponseBuilder<>(publisher,
BodyInserters.fromPublisher(publisher, elementClass))
@ -208,8 +219,8 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -208,8 +219,8 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
public <T, P extends Publisher<T>> Mono<ServerResponse> body(P publisher,
ParameterizedTypeReference<T> typeReference) {
Assert.notNull(publisher, "'publisher' must not be null");
Assert.notNull(typeReference, "'typeReference' must not be null");
Assert.notNull(publisher, "Publisher must not be null");
Assert.notNull(typeReference, "ParameterizedTypeReference must not be null");
return new DefaultEntityResponseBuilder<>(publisher,
BodyInserters.fromPublisher(publisher, typeReference))
@ -221,9 +232,9 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -221,9 +232,9 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public Mono<ServerResponse> syncBody(Object body) {
Assert.notNull(body, "'body' must not be null");
Assert.isTrue(!(body instanceof Publisher), "Please specify the element class by using " +
"body(Publisher, Class)");
Assert.notNull(body, "Body must not be null");
Assert.isTrue(!(body instanceof Publisher),
"Please specify the element class by using body(Publisher, Class)");
return new DefaultEntityResponseBuilder<>(body,
BodyInserters.fromObject(body))
@ -235,14 +246,14 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -235,14 +246,14 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public Mono<ServerResponse> body(BodyInserter<?, ? super ServerHttpResponse> inserter) {
Assert.notNull(inserter, "'inserter' must not be null");
return Mono.just(new BodyInserterServerResponse<>(this.statusCode, this.headers,
this.cookies, inserter, this.hints));
Assert.notNull(inserter, "BodyInserter must not be null");
return Mono.just(
new BodyInserterServerResponse<>(this.statusCode, this.headers, this.cookies, inserter, this.hints));
}
@Override
public Mono<ServerResponse> render(String name, Object... modelAttributes) {
Assert.hasLength(name, "'name' must not be empty");
Assert.hasLength(name, "Name must not be empty");
return new DefaultRenderingResponseBuilder(name)
.headers(this.headers)
@ -254,7 +265,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -254,7 +265,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public Mono<ServerResponse> render(String name, Map<String, ?> model) {
Assert.hasLength(name, "'name' must not be empty");
Assert.hasLength(name, "Name must not be empty");
return new DefaultRenderingResponseBuilder(name)
.headers(this.headers)
@ -267,14 +278,15 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -267,14 +278,15 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
static abstract class AbstractServerResponse implements ServerResponse {
private final HttpStatus statusCode;
final int statusCode;
private final HttpHeaders headers;
private final MultiValueMap<String, ResponseCookie> cookies;
protected AbstractServerResponse(HttpStatus statusCode, HttpHeaders headers,
protected AbstractServerResponse(int statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies) {
this.statusCode = statusCode;
this.headers = readOnlyCopy(headers);
this.cookies = readOnlyCopy(cookies);
@ -294,7 +306,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -294,7 +306,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
@Override
public final HttpStatus statusCode() {
return this.statusCode;
return HttpStatus.valueOf(this.statusCode);
}
@Override
@ -308,8 +320,17 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -308,8 +320,17 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
}
protected void writeStatusAndHeaders(ServerHttpResponse response) {
response.setStatusCode(this.statusCode);
if (response instanceof AbstractServerHttpResponse) {
((AbstractServerHttpResponse) response).setStatusCodeValue(this.statusCode);
}
else {
HttpStatus status = HttpStatus.resolve(this.statusCode);
if (status == null) {
throw new IllegalStateException(
"Unresolvable HttpStatus for general ServerHttpResponse: " + this.statusCode);
}
response.setStatusCode(status);
}
copy(this.headers, response.getHeaders());
copy(this.cookies, response.getCookies());
}
@ -328,7 +349,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -328,7 +349,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
private final BiFunction<ServerWebExchange, Context, Mono<Void>> writeFunction;
public WriterFunctionServerResponse(HttpStatus statusCode, HttpHeaders headers,
public WriterFunctionServerResponse(int statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies,
BiFunction<ServerWebExchange, Context, Mono<Void>> writeFunction) {
@ -350,7 +371,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { @@ -350,7 +371,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
private final Map<String, Object> hints;
public BodyInserterServerResponse(HttpStatus statusCode, HttpHeaders headers,
public BodyInserterServerResponse(int statusCode, HttpHeaders headers,
MultiValueMap<String, ResponseCookie> cookies,
BodyInserter<T, ? super ServerHttpResponse> inserter, Map<String, Object> hints) {

13
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -41,6 +41,7 @@ import org.springframework.web.reactive.function.BodyInserters; @@ -41,6 +41,7 @@ import org.springframework.web.reactive.function.BodyInserters;
* Entity-specific subtype of {@link ServerResponse} that exposes entity data.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
public interface EntityResponse<T> extends ServerResponse {
@ -120,12 +121,20 @@ public interface EntityResponse<T> extends ServerResponse { @@ -120,12 +121,20 @@ public interface EntityResponse<T> extends ServerResponse {
Builder<T> headers(HttpHeaders headers);
/**
* Set the status.
* Set the HTTP status.
* @param status the response status
* @return this builder
*/
Builder<T> status(HttpStatus status);
/**
* Set the HTTP status.
* @param status the response status
* @return this builder
* @since 5.0.3
*/
Builder<T> status(int status);
/**
* Add the given cookie to the response.
* @param cookie the cookie to add

21
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RenderingResponse.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -33,6 +33,7 @@ import org.springframework.util.MultiValueMap; @@ -33,6 +33,7 @@ import org.springframework.util.MultiValueMap;
* Rendering-specific subtype of {@link ServerResponse} that exposes model and template data.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
public interface RenderingResponse extends ServerResponse {
@ -56,12 +57,8 @@ public interface RenderingResponse extends ServerResponse { @@ -56,12 +57,8 @@ public interface RenderingResponse extends ServerResponse {
* @return the created builder
*/
static Builder from(RenderingResponse other) {
Assert.notNull(other, "'other' must not be null");
DefaultRenderingResponseBuilder builder = new DefaultRenderingResponseBuilder(other.name());
builder.status(other.statusCode());
builder.headers(other.headers());
builder.modelAttributes(other.model());
return builder;
Assert.notNull(other, "Other RenderingResponse must not be null");
return new DefaultRenderingResponseBuilder(other);
}
/**
@ -136,12 +133,20 @@ public interface RenderingResponse extends ServerResponse { @@ -136,12 +133,20 @@ public interface RenderingResponse extends ServerResponse {
Builder headers(HttpHeaders headers);
/**
* Set the status.
* Set the HTTP status.
* @param status the response status
* @return this builder
*/
Builder status(HttpStatus status);
/**
* Set the HTTP status.
* @param status the response status
* @return this builder
* @since 5.0.3
*/
Builder status(int status);
/**
* Add the given cookie to the response.
* @param cookie the cookie to add

19
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -51,6 +51,7 @@ import org.springframework.web.server.ServerWebExchange; @@ -51,6 +51,7 @@ import org.springframework.web.server.ServerWebExchange;
* {@linkplain HandlerFilterFunction filter function}.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @since 5.0
*/
@ -91,12 +92,11 @@ public interface ServerResponse { @@ -91,12 +92,11 @@ public interface ServerResponse {
*/
static BodyBuilder from(ServerResponse other) {
Assert.notNull(other, "Other ServerResponse must not be null");
DefaultServerResponseBuilder builder = new DefaultServerResponseBuilder(other.statusCode());
return builder.headers(headers -> headers.addAll(other.headers()));
return new DefaultServerResponseBuilder(other);
}
/**
* Create a builder with the given status.
* Create a builder with the given HTTP status.
* @param status the response status
* @return the created builder
*/
@ -105,6 +105,16 @@ public interface ServerResponse { @@ -105,6 +105,16 @@ public interface ServerResponse {
return new DefaultServerResponseBuilder(status);
}
/**
* Create a builder with the given HTTP status.
* @param status the response status
* @return the created builder
* @since 5.0.3
*/
static BodyBuilder status(int status) {
return new DefaultServerResponseBuilder(status);
}
/**
* Create a builder with the status set to {@linkplain HttpStatus#OK 200 OK}.
* @return the created builder
@ -450,5 +460,4 @@ public interface ServerResponse { @@ -450,5 +460,4 @@ public interface ServerResponse {
List<ViewResolver> viewResolvers();
}
}

Loading…
Cancel
Save