|
|
|
@ -47,6 +47,7 @@ import org.springframework.web.server.ServerWebExchange; |
|
|
|
* Base class for {@link View} implementations. |
|
|
|
* Base class for {@link View} implementations. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
|
|
|
|
* @author Sam Brannen |
|
|
|
* @since 5.0 |
|
|
|
* @since 5.0 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public abstract class AbstractView implements View, BeanNameAware, ApplicationContextAware { |
|
|
|
public abstract class AbstractView implements View, BeanNameAware, ApplicationContextAware { |
|
|
|
@ -86,7 +87,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the supported media types for this view. |
|
|
|
* Set the supported media types for this view. |
|
|
|
* Default is "text/html;charset=UTF-8". |
|
|
|
* <p>Default is {@code "text/html;charset=UTF-8"}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) { |
|
|
|
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) { |
|
|
|
Assert.notEmpty(supportedMediaTypes, "MediaType List must not be empty"); |
|
|
|
Assert.notEmpty(supportedMediaTypes, "MediaType List must not be empty"); |
|
|
|
@ -95,7 +96,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the configured media types supported by this view. |
|
|
|
* Get the configured media types supported by this view. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public List<MediaType> getSupportedMediaTypes() { |
|
|
|
public List<MediaType> getSupportedMediaTypes() { |
|
|
|
@ -105,7 +106,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the default charset for this view, used when the |
|
|
|
* Set the default charset for this view, used when the |
|
|
|
* {@linkplain #setSupportedMediaTypes(List) content type} does not contain one. |
|
|
|
* {@linkplain #setSupportedMediaTypes(List) content type} does not contain one. |
|
|
|
* Default is {@linkplain StandardCharsets#UTF_8 UTF 8}. |
|
|
|
* <p>Default is {@linkplain StandardCharsets#UTF_8 UTF 8}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setDefaultCharset(Charset defaultCharset) { |
|
|
|
public void setDefaultCharset(Charset defaultCharset) { |
|
|
|
Assert.notNull(defaultCharset, "'defaultCharset' must not be null"); |
|
|
|
Assert.notNull(defaultCharset, "'defaultCharset' must not be null"); |
|
|
|
@ -113,7 +114,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the default charset, used when the |
|
|
|
* Get the default charset, used when the |
|
|
|
* {@linkplain #setSupportedMediaTypes(List) content type} does not contain one. |
|
|
|
* {@linkplain #setSupportedMediaTypes(List) content type} does not contain one. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Charset getDefaultCharset() { |
|
|
|
public Charset getDefaultCharset() { |
|
|
|
@ -121,15 +122,15 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the name of the RequestContext attribute for this view. |
|
|
|
* Set the name of the {@code RequestContext} attribute for this view. |
|
|
|
* Default is none. |
|
|
|
* <p>Default is none ({@code null}). |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setRequestContextAttribute(@Nullable String requestContextAttribute) { |
|
|
|
public void setRequestContextAttribute(@Nullable String requestContextAttribute) { |
|
|
|
this.requestContextAttribute = requestContextAttribute; |
|
|
|
this.requestContextAttribute = requestContextAttribute; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the name of the RequestContext attribute, if any. |
|
|
|
* Get the name of the {@code RequestContext} attribute for this view, if any. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
public String getRequestContextAttribute() { |
|
|
|
public String getRequestContextAttribute() { |
|
|
|
@ -146,8 +147,8 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the view's name. Should never be {@code null}, if the view was |
|
|
|
* Get the view's name. |
|
|
|
* correctly configured. |
|
|
|
* <p>Should never be {@code null} if the view was correctly configured. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
public String getBeanName() { |
|
|
|
public String getBeanName() { |
|
|
|
@ -165,9 +166,10 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Obtain the ApplicationContext for actual use. |
|
|
|
* Obtain the {@link ApplicationContext} for actual use. |
|
|
|
* @return the ApplicationContext (never {@code null}) |
|
|
|
* @return the {@code ApplicationContext} (never {@code null}) |
|
|
|
* @throws IllegalStateException in case of no ApplicationContext set |
|
|
|
* @throws IllegalStateException if the ApplicationContext cannot be obtained |
|
|
|
|
|
|
|
* @see #getApplicationContext() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected final ApplicationContext obtainApplicationContext() { |
|
|
|
protected final ApplicationContext obtainApplicationContext() { |
|
|
|
ApplicationContext applicationContext = getApplicationContext(); |
|
|
|
ApplicationContext applicationContext = getApplicationContext(); |
|
|
|
@ -178,12 +180,12 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Prepare the model to render. |
|
|
|
* Prepare the model to render. |
|
|
|
* @param model a Map with name Strings as keys and corresponding model |
|
|
|
* @param model a map with attribute names as keys and corresponding model |
|
|
|
* objects as values (Map can also be {@code null} in case of empty model) |
|
|
|
* objects as values (the map can also be {@code null} in case of an empty model) |
|
|
|
* @param contentType the content type selected to render with which should |
|
|
|
* @param contentType the content type selected to render with, which should |
|
|
|
* match one of the {@link #getSupportedMediaTypes() supported media types}. |
|
|
|
* match one of the {@link #getSupportedMediaTypes() supported media types} |
|
|
|
* @param exchange the current exchange |
|
|
|
* @param exchange the current exchange |
|
|
|
* @return {@code Mono} to represent when and if rendering succeeds |
|
|
|
* @return a {@code Mono} that represents when and if rendering succeeds |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, |
|
|
|
public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, |
|
|
|
@ -239,9 +241,9 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
* Use the configured {@link ReactiveAdapterRegistry} to adapt asynchronous |
|
|
|
* Use the configured {@link ReactiveAdapterRegistry} to adapt asynchronous |
|
|
|
* attributes to {@code Mono<T>} or {@code Mono<List<T>>} and then wait to |
|
|
|
* attributes to {@code Mono<T>} or {@code Mono<List<T>>} and then wait to |
|
|
|
* resolve them into actual values. When the returned {@code Mono<Void>} |
|
|
|
* resolve them into actual values. When the returned {@code Mono<Void>} |
|
|
|
* completes, the asynchronous attributes in the model would have been |
|
|
|
* completes, the asynchronous attributes in the model will have been |
|
|
|
* replaced with their corresponding resolved values. |
|
|
|
* replaced with their corresponding resolved values. |
|
|
|
* @return result {@code Mono} that completes when the model is ready |
|
|
|
* @return result a {@code Mono} that completes when the model is ready |
|
|
|
* @since 5.1.8 |
|
|
|
* @since 5.1.8 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected Mono<Void> resolveAsyncAttributes(Map<String, Object> model, ServerWebExchange exchange) { |
|
|
|
protected Mono<Void> resolveAsyncAttributes(Map<String, Object> model, ServerWebExchange exchange) { |
|
|
|
@ -299,7 +301,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
* replaced with their corresponding resolved values. |
|
|
|
* replaced with their corresponding resolved values. |
|
|
|
* @return result {@code Mono} that completes when the model is ready |
|
|
|
* @return result {@code Mono} that completes when the model is ready |
|
|
|
* @deprecated as of 5.1.8 this method is still invoked but it is a no-op. |
|
|
|
* @deprecated as of 5.1.8 this method is still invoked but it is a no-op. |
|
|
|
* Please, use {@link #resolveAsyncAttributes(Map, ServerWebExchange)} |
|
|
|
* Please use {@link #resolveAsyncAttributes(Map, ServerWebExchange)} |
|
|
|
* instead. It is invoked after this one and does the actual work. |
|
|
|
* instead. It is invoked after this one and does the actual work. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Deprecated |
|
|
|
@Deprecated |
|
|
|
@ -308,14 +310,15 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a RequestContext to expose under the specified attribute name. |
|
|
|
* Create a {@link RequestContext} to expose under the |
|
|
|
* <p>The default implementation creates a standard RequestContext instance |
|
|
|
* {@linkplain #setRequestContextAttribute specified attribute name}. |
|
|
|
* for the given request and model. Can be overridden in subclasses for |
|
|
|
* <p>The default implementation creates a standard {@code RequestContext} |
|
|
|
* custom instances. |
|
|
|
* instance for the given exchange and model. |
|
|
|
* @param exchange current exchange |
|
|
|
* <p>Can be overridden in subclasses to create custom instances. |
|
|
|
* @param model combined output Map (never {@code null}), |
|
|
|
* @param exchange the current exchange |
|
|
|
* with dynamic values taking precedence over static attributes |
|
|
|
* @param model a combined output Map (never {@code null}), with dynamic values |
|
|
|
* @return the RequestContext instance |
|
|
|
* taking precedence over static attributes |
|
|
|
|
|
|
|
* @return the {@code RequestContext} instance |
|
|
|
* @see #setRequestContextAttribute |
|
|
|
* @see #setRequestContextAttribute |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected RequestContext createRequestContext(ServerWebExchange exchange, Map<String, Object> model) { |
|
|
|
protected RequestContext createRequestContext(ServerWebExchange exchange, Map<String, Object> model) { |
|
|
|
@ -323,12 +326,12 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the {@link RequestDataValueProcessor} to use. |
|
|
|
* Get the {@link RequestDataValueProcessor} to use. |
|
|
|
* <p>The default implementation looks in the {@link #getApplicationContext() |
|
|
|
* <p>The default implementation looks in the {@link #getApplicationContext() |
|
|
|
* Spring configuration} for a {@code RequestDataValueProcessor} bean with |
|
|
|
* ApplicationContext} for a {@code RequestDataValueProcessor} bean with |
|
|
|
* the name {@link #REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME}. |
|
|
|
* the name {@link #REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME}. |
|
|
|
* @return the RequestDataValueProcessor, or null if there is none at the |
|
|
|
* @return the {@code RequestDataValueProcessor}, or {@code null} if there is |
|
|
|
* application context. |
|
|
|
* none in the application context |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
protected RequestDataValueProcessor getRequestDataValueProcessor() { |
|
|
|
protected RequestDataValueProcessor getRequestDataValueProcessor() { |
|
|
|
@ -343,10 +346,10 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo |
|
|
|
* Subclasses must implement this method to actually render the view. |
|
|
|
* Subclasses must implement this method to actually render the view. |
|
|
|
* @param renderAttributes combined output Map (never {@code null}), |
|
|
|
* @param renderAttributes combined output Map (never {@code null}), |
|
|
|
* with dynamic values taking precedence over static attributes |
|
|
|
* with dynamic values taking precedence over static attributes |
|
|
|
* @param contentType the content type selected to render with which should |
|
|
|
* @param contentType the content type selected to render with, which should |
|
|
|
* match one of the {@link #getSupportedMediaTypes() supported media types}. |
|
|
|
* match one of the {@linkplain #getSupportedMediaTypes() supported media types} |
|
|
|
*@param exchange current exchange @return {@code Mono} to represent when |
|
|
|
* @param exchange current exchange |
|
|
|
* and if rendering succeeds |
|
|
|
* @return a {@code Mono} that represents when and if rendering succeeds |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected abstract Mono<Void> renderInternal(Map<String, Object> renderAttributes, |
|
|
|
protected abstract Mono<Void> renderInternal(Map<String, Object> renderAttributes, |
|
|
|
@Nullable MediaType contentType, ServerWebExchange exchange); |
|
|
|
@Nullable MediaType contentType, ServerWebExchange exchange); |
|
|
|
|