/** * Prepare the model to render. * @param model a Map with name Strings as keys and corresponding model * objects as values (Map can also be {@code null} in case of empty model) * @param contentType the content type selected to render with which should * match one of the {@link #getSupportedMediaTypes() supported media types}. * @param exchange the current exchange * @return {@code Mono} to represent when and if rendering succeeds */ @Override public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType, ServerWebExchange exchange) { if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "View " + formatViewName() + ", model " + (model != null ? model : Collections.emptyMap())); } if (contentType != null) { exchange.getResponse().getHeaders().setContentType(contentType); } return getModelAttributes(model, exchange).flatMap(mergedModel -> { // Expose RequestContext? if (this.requestContextAttribute != null) { mergedModel.put(this.requestContextAttribute, createRequestContext(exchange, mergedModel)); } return renderInternal(mergedModel, contentType, exchange); }); }
/** * Obtain the ApplicationContext for actual use. * @return the ApplicationContext (never {@code null}) * @throws IllegalStateException in case of no ApplicationContext set */ protected final ApplicationContext obtainApplicationContext() { ApplicationContext applicationContext = getApplicationContext(); Assert.state(applicationContext != null, "No ApplicationContext"); return applicationContext; }
/** * Create a RequestContext to expose under the specified attribute name. * <p>The default implementation creates a standard RequestContext instance * for the given request and model. Can be overridden in subclasses for * custom instances. * @param exchange current exchange * @param model combined output Map (never {@code null}), * with dynamic values taking precedence over static attributes * @return the RequestContext instance * @see #setRequestContextAttribute */ protected RequestContext createRequestContext(ServerWebExchange exchange, Map<String, Object> model) { return new RequestContext(exchange, model, obtainApplicationContext(), getRequestDataValueProcessor()); }
/** * Prepare the model to render. * @param model Map with name Strings as keys and corresponding model * objects as values (Map can also be {@code null} in case of empty model) * @param contentType the content type selected to render with which should * match one of the {@link #getSupportedMediaTypes() supported media types}. * @param exchange the current exchange * @return {@code Mono} to represent when and if rendering succeeds */ @Override public Mono<Void> render(Map<String, ?> model, MediaType contentType, ServerWebExchange exchange) { if (logger.isTraceEnabled()) { logger.trace("Rendering view with model " + model); } if (contentType != null) { exchange.getResponse().getHeaders().setContentType(contentType); } Map<String, Object> mergedModel = getModelAttributes(model, exchange); // Expose RequestContext? if (this.requestContextAttribute != null) { mergedModel.put(this.requestContextAttribute, createRequestContext(exchange, mergedModel)); } return renderInternal(mergedModel, contentType, exchange); }
/** * Create a RequestContext to expose under the specified attribute name. * <p>The default implementation creates a standard RequestContext instance for the * given request and model. Can be overridden in subclasses for custom instances. * @param exchange current exchange * @param model combined output Map (never {@code null}), * with dynamic values taking precedence over static attributes * @return the RequestContext instance * @see #setRequestContextAttribute */ protected RequestContext createRequestContext(ServerWebExchange exchange, Map<String, Object> model) { return new RequestContext(exchange, model, getApplicationContext(), getRequestDataValueProcessor()); }
@Override public String toString() { return super.toString() + "; URL [" + getUrl() + "]"; }
protected String formatViewName() { return (getBeanName() != null ? "name '" + getBeanName() + "'" : "[" + getClass().getSimpleName() + "]"); }
@Override public String toString() { return getClass().getName() + ": " + formatViewName(); }
return super.render(enrichedModel, contentType, exchange);
@Override public String toString() { return super.toString() + "; URL [" + getUrl() + "]"; }
/** * Return the {@link RequestDataValueProcessor} to use. * <p>The default implementation looks in the {@link #getApplicationContext() * Spring configuration} for a {@code RequestDataValueProcessor} bean with * the name {@link #REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME}. * @return the RequestDataValueProcessor, or null if there is none at the * application context. */ @Nullable protected RequestDataValueProcessor getRequestDataValueProcessor() { ApplicationContext context = getApplicationContext(); if (context != null && context.containsBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) { return context.getBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME, RequestDataValueProcessor.class); } return null; }
/** * Return the {@link RequestDataValueProcessor} to use. * <p>The default implementation looks in the {@link #getApplicationContext() * Spring configuration} for a {@code RequestDataValueProcessor} bean with * the name {@link #REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME}. */ protected RequestDataValueProcessor getRequestDataValueProcessor() { if (getApplicationContext() != null) { String beanName = REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME; return getApplicationContext().getBean(beanName, RequestDataValueProcessor.class); } return null; }