diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java index 28e11eb895..fe39b75f76 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java @@ -28,9 +28,7 @@ import reactor.core.publisher.Mono; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.http.MediaType; -import org.springframework.ui.ModelMap; import org.springframework.util.Assert; -import org.springframework.web.reactive.HandlerResult; import org.springframework.web.server.ServerWebExchange; /** @@ -84,28 +82,28 @@ public abstract class AbstractView implements View, ApplicationContextAware { return applicationContext; } - /** * Prepare the model to render. - * @param result the result from handler execution + * @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 render(HandlerResult result, MediaType contentType, + public Mono render(Map model, MediaType contentType, ServerWebExchange exchange) { if (logger.isTraceEnabled()) { - logger.trace("Rendering view with model " + result.getModel()); + logger.trace("Rendering view with model " + model); } if (contentType != null) { exchange.getResponse().getHeaders().setContentType(contentType); } - Map mergedModel = getModelAttributes(result, exchange); + Map mergedModel = getModelAttributes(model, exchange); return renderInternal(mergedModel, exchange); } @@ -114,8 +112,7 @@ public abstract class AbstractView implements View, ApplicationContextAware { *

The default implementation creates a combined output Map that includes * model as well as static attributes with the former taking precedence. */ - protected Map getModelAttributes(HandlerResult result, ServerWebExchange exchange) { - ModelMap model = result.getModel(); + protected Map getModelAttributes(Map model, ServerWebExchange exchange) { int size = (model != null ? model.size() : 0); Map attributes = new LinkedHashMap<>(size); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/HttpMessageWriterView.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/HttpMessageWriterView.java index 4922c12702..b35de21100 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/HttpMessageWriterView.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/HttpMessageWriterView.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.HashMap; @@ -30,9 +31,7 @@ import org.springframework.http.MediaType; import org.springframework.http.codec.EncoderHttpMessageWriter; import org.springframework.http.codec.HttpMessageWriter; import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.ui.ModelMap; import org.springframework.util.Assert; -import org.springframework.web.reactive.HandlerResult; import org.springframework.web.server.ServerWebExchange; @@ -105,15 +104,15 @@ public class HttpMessageWriterView implements View { } @Override - public Mono render(HandlerResult result, MediaType contentType, ServerWebExchange exchange) { - Object value = extractObjectToRender(result); + public Mono render(Map model, MediaType contentType, + ServerWebExchange exchange) { + Object value = extractObjectToRender(model); return applyMessageWriter(value, contentType, exchange); } - protected Object extractObjectToRender(HandlerResult result) { - ModelMap model = result.getModel(); + protected Object extractObjectToRender(Map model) { Map map = new HashMap<>(model.size()); - for (Map.Entry entry : model.entrySet()) { + for (Map.Entry entry : model.entrySet()) { if (isEligibleAttribute(entry.getKey(), entry.getValue())) { map.put(entry.getKey(), entry.getValue()); } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/View.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/View.java index 02f871cc35..b35c240173 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/View.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/View.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.util.List; +import java.util.Map; import reactor.core.publisher.Mono; @@ -48,12 +50,13 @@ public interface View { /** * Render the view based on the given {@link HandlerResult}. Implementations * can access and use the model or only a specific attribute in it. - * @param result the result from handler execution + * @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 */ - Mono render(HandlerResult result, MediaType contentType, ServerWebExchange exchange); + Mono render(Map model, MediaType contentType, ServerWebExchange exchange); } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index b9c1e40015..0dcb351830 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view; import java.lang.reflect.Method; @@ -205,15 +206,15 @@ public class ViewResolutionResultHandler extends ContentNegotiatingResultHandler .defaultIfEmpty(result.getModel()) .then(model -> getDefaultViewNameMono(exchange, result)); } - + Map model = result.getModel(); return viewMono.then(view -> { if (view instanceof View) { - return ((View) view).render(result, null, exchange); + return ((View) view).render(model, null, exchange); } else if (view instanceof CharSequence) { String viewName = view.toString(); Locale locale = Locale.getDefault(); // TODO - return resolveAndRender(viewName, locale, result, exchange); + return resolveAndRender(viewName, locale, model, exchange); } else { @@ -305,7 +306,7 @@ public class ViewResolutionResultHandler extends ContentNegotiatingResultHandler } private Mono resolveAndRender(String viewName, Locale locale, - HandlerResult result, ServerWebExchange exchange) { + Map model, ServerWebExchange exchange) { return Flux.fromIterable(getViewResolvers()) .concatMap(resolver -> resolver.resolveViewName(viewName, locale)) @@ -323,7 +324,7 @@ public class ViewResolutionResultHandler extends ContentNegotiatingResultHandler for (View view : views) { for (MediaType supported : view.getSupportedMediaTypes()) { if (supported.isCompatibleWith(bestMediaType)) { - return view.render(result, bestMediaType, exchange); + return view.render(model, bestMediaType, exchange); } } } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java index b1884d4279..dd0c2e65c2 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java @@ -25,10 +25,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.junit.Before; import org.junit.Test; -import org.springframework.core.MethodParameter; import org.springframework.core.codec.CharSequenceEncoder; import org.springframework.core.io.buffer.support.DataBufferTestUtils; import org.springframework.http.HttpMethod; @@ -41,18 +39,13 @@ import org.springframework.tests.TestSubscriber; import org.springframework.ui.ExtendedModelMap; import org.springframework.ui.ModelMap; import org.springframework.util.MimeType; -import org.springframework.web.reactive.HandlerResult; -import org.springframework.web.reactive.result.ResolvableMethod; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.session.DefaultWebSessionManager; import org.springframework.web.server.session.WebSessionManager; import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; /** @@ -63,18 +56,9 @@ public class HttpMessageWriterViewTests { private HttpMessageWriterView view = new HttpMessageWriterView(new Jackson2JsonEncoder()); - private HandlerResult result; - private ModelMap model = new ExtendedModelMap(); - @Before - public void setup() throws Exception { - MethodParameter param = ResolvableMethod.onClass(this.getClass()).name("handle").resolveReturnType(); - this.result = new HandlerResult(this, null, param, this.model); - } - - @Test public void supportedMediaTypes() throws Exception { List mimeTypes = Arrays.asList( @@ -91,7 +75,7 @@ public class HttpMessageWriterViewTests { this.model.addAttribute("foo2", "bar2"); this.model.addAttribute("foo3", "bar3"); - assertEquals("bar2", this.view.extractObjectToRender(this.result)); + assertEquals("bar2", this.view.extractObjectToRender(this.model)); } @Test @@ -99,7 +83,7 @@ public class HttpMessageWriterViewTests { this.view.setModelKeys(Collections.singleton("foo2")); this.model.addAttribute("foo1", "bar1"); - assertNull(this.view.extractObjectToRender(this.result)); + assertNull(this.view.extractObjectToRender(this.model)); } @Test @@ -109,7 +93,7 @@ public class HttpMessageWriterViewTests { this.model.addAttribute("foo2", "bar2"); this.model.addAttribute("foo3", "bar3"); - Object value = this.view.extractObjectToRender(this.result); + Object value = this.view.extractObjectToRender(this.model); assertNotNull(value); assertEquals(HashMap.class, value.getClass()); @@ -127,7 +111,7 @@ public class HttpMessageWriterViewTests { this.model.addAttribute("foo2", "bar2"); try { - view.extractObjectToRender(this.result); + view.extractObjectToRender(this.model); fail(); } catch (IllegalStateException ex) { @@ -143,7 +127,7 @@ public class HttpMessageWriterViewTests { this.model.addAttribute("foo1", "bar1"); try { - view.extractObjectToRender(this.result); + view.extractObjectToRender(this.model); fail(); } catch (IllegalStateException ex) { @@ -165,7 +149,7 @@ public class HttpMessageWriterViewTests { WebSessionManager manager = new DefaultWebSessionManager(); ServerWebExchange exchange = new DefaultServerWebExchange(request, response, manager); - this.view.render(result, MediaType.APPLICATION_JSON, exchange); + this.view.render(this.model, MediaType.APPLICATION_JSON, exchange); TestSubscriber .subscribe(response.getBody()) diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java index c35bc8106f..6c68cebf61 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java @@ -347,8 +347,9 @@ public class ViewResolutionResultHandlerTests { } @Override - public Mono render(HandlerResult result, MediaType mediaType, ServerWebExchange exchange) { - String value = this.name + ": " + result.getModel().toString(); + public Mono render(Map model, MediaType mediaType, + ServerWebExchange exchange) { + String value = this.name + ": " + model.toString(); assertNotNull(value); ServerHttpResponse response = exchange.getResponse(); if (mediaType != null) { diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewTests.java index 7660a037ce..465b181837 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.result.view.freemarker; import java.nio.ByteBuffer; @@ -27,7 +28,6 @@ import org.junit.rules.ExpectedException; import org.springframework.context.ApplicationContextException; import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.MethodParameter; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpMethod; import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; @@ -35,7 +35,6 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse import org.springframework.tests.TestSubscriber; import org.springframework.ui.ExtendedModelMap; import org.springframework.ui.ModelMap; -import org.springframework.web.reactive.HandlerResult; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.session.DefaultWebSessionManager; @@ -122,9 +121,7 @@ public class FreeMarkerViewTests { ModelMap model = new ExtendedModelMap(); model.addAttribute("hello", "hi FreeMarker"); - MethodParameter returnType = new MethodParameter(getClass().getDeclaredMethod("handle"), -1); - HandlerResult result = new HandlerResult(new Object(), "", returnType, model); - view.render(result, null, this.exchange); + view.render(model, null, this.exchange); TestSubscriber .subscribe(this.response.getBody())