diff --git a/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesView.java b/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesView.java index 0006a488cc..8a9cb2dc56 100644 --- a/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesView.java +++ b/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -48,12 +48,27 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView; * {@link TilesConfigurer} bean definition in the application context. * * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 2.5 * @see #setUrl * @see TilesConfigurer */ public class TilesView extends AbstractUrlBasedView { + private boolean alwaysInclude = false; + + + /** + * Specify whether to always include the view rather than forward to it. + *

Default is "false". Switch this flag on to enforce the use of a + * Servlet include, even if a forward would be possible. + * @see TilesViewResolver#setAlwaysInclude(Boolean) + * @since 4.1.2 + */ + public void setAlwaysInclude(boolean alwaysInclude) { + this.alwaysInclude = alwaysInclude; + } + @Override public boolean checkResource(final Locale locale) throws Exception { TilesContainer container = ServletUtil.getContainer(getServletContext()); @@ -85,6 +100,9 @@ public class TilesView extends AbstractUrlBasedView { exposeModelAsRequestAttributes(model, request); JstlUtils.exposeLocalizationContext(new RequestContext(request, servletContext)); + if (this.alwaysInclude) { + ServletUtil.setForceInclude(request, true); + } container.render(getUrl(), request, response); } diff --git a/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesViewResolver.java b/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesViewResolver.java index f559d4de95..9da49e68d5 100644 --- a/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesViewResolver.java +++ b/spring-webmvc-tiles2/src/main/java/org/springframework/web/servlet/view/tiles2/TilesViewResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2014 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. @@ -16,6 +16,7 @@ package org.springframework.web.servlet.view.tiles2; +import org.springframework.web.servlet.view.AbstractUrlBasedView; import org.springframework.web.servlet.view.UrlBasedViewResolver; /** @@ -30,6 +31,7 @@ import org.springframework.web.servlet.view.UrlBasedViewResolver; * a non-null View object if the template was actually found. * * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.0 * @see #setViewClass * @see #setPrefix @@ -39,10 +41,24 @@ import org.springframework.web.servlet.view.UrlBasedViewResolver; */ public class TilesViewResolver extends UrlBasedViewResolver { + private Boolean alwaysInclude; + + public TilesViewResolver() { setViewClass(requiredViewClass()); } + /** + * Specify whether to always include the view rather than forward to it. + *

Default is "false". Switch this flag on to enforce the use of a + * Servlet include, even if a forward would be possible. + * @see TilesView#setAlwaysInclude + * @since 4.1.2 + */ + public void setAlwaysInclude(Boolean alwaysInclude) { + this.alwaysInclude = alwaysInclude; + } + /** * Requires {@link TilesView}. */ @@ -51,4 +67,13 @@ public class TilesViewResolver extends UrlBasedViewResolver { return TilesView.class; } + @Override + protected AbstractUrlBasedView buildView(String viewName) throws Exception { + TilesView view = (TilesView) super.buildView(viewName); + if (this.alwaysInclude != null) { + view.setAlwaysInclude(this.alwaysInclude); + } + return view; + } + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java index 1ce5c9af22..40e15d59eb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.tiles.TilesContainer; import org.apache.tiles.access.TilesAccess; import org.apache.tiles.renderer.DefinitionRenderer; +import org.apache.tiles.request.AbstractRequest; import org.apache.tiles.request.ApplicationContext; import org.apache.tiles.request.Request; import org.apache.tiles.request.render.Renderer; @@ -46,6 +47,7 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView; * @author Nicolas Le Bas * @author mick semb wever * @author Rossen Stoyanchev + * @author Sebastien Deleuze * @since 3.2 */ public class TilesView extends AbstractUrlBasedView { @@ -54,6 +56,8 @@ public class TilesView extends AbstractUrlBasedView { private boolean exposeJstlAttributes = true; + private boolean alwaysInclude = false; + private ApplicationContext applicationContext; @@ -73,6 +77,17 @@ public class TilesView extends AbstractUrlBasedView { this.exposeJstlAttributes = exposeJstlAttributes; } + /** + * Specify whether to always include the view rather than forward to it. + *

Default is "false". Switch this flag on to enforce the use of a + * Servlet include, even if a forward would be possible. + * @see TilesViewResolver#setAlwaysInclude(Boolean) + * @since 4.1.2 + */ + public void setAlwaysInclude(boolean alwaysInclude) { + this.alwaysInclude = alwaysInclude; + } + @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); @@ -84,7 +99,6 @@ public class TilesView extends AbstractUrlBasedView { } } - @Override public boolean checkResource(final Locale locale) throws Exception { HttpServletRequest servletRequest = null; @@ -109,6 +123,9 @@ public class TilesView extends AbstractUrlBasedView { if (this.exposeJstlAttributes) { JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext())); } + if (this.alwaysInclude) { + request.setAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME, true); + } Request tilesRequest = createTilesRequest(request, response); this.renderer.render(getUrl(), tilesRequest); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java index a134e8641c..b8c9f24835 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles3/TilesViewResolver.java @@ -27,26 +27,20 @@ import org.springframework.web.servlet.view.UrlBasedViewResolver; * @author Nicolas Le Bas * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.2 */ public class TilesViewResolver extends UrlBasedViewResolver { private Renderer renderer; + private Boolean alwaysInclude; + public TilesViewResolver() { setViewClass(requiredViewClass()); } - - /** - * Requires {@link TilesView}. - */ - @Override - protected Class requiredViewClass() { - return TilesView.class; - } - /** * Set the {@link Renderer} to use. If not specified, a default * {@link org.apache.tiles.renderer.DefinitionRenderer} will be used. @@ -56,6 +50,24 @@ public class TilesViewResolver extends UrlBasedViewResolver { this.renderer = renderer; } + /** + * Specify whether to always include the view rather than forward to it. + *

Default is "false". Switch this flag on to enforce the use of a + * Servlet include, even if a forward would be possible. + * @see TilesView#setAlwaysInclude + * @since 4.1.2 + */ + public void setAlwaysInclude(Boolean alwaysInclude) { + this.alwaysInclude = alwaysInclude; + } + + /** + * Requires {@link TilesView}. + */ + @Override + protected Class requiredViewClass() { + return TilesView.class; + } @Override protected TilesView buildView(String viewName) throws Exception { @@ -63,6 +75,9 @@ public class TilesViewResolver extends UrlBasedViewResolver { if (this.renderer != null) { view.setRenderer(this.renderer); } + if (this.alwaysInclude != null) { + view.setAlwaysInclude(this.alwaysInclude); + } return view; } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java index 592f178217..e8099b1148 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/tiles3/TilesViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -18,6 +18,7 @@ package org.springframework.web.servlet.view.tiles3; import java.util.HashMap; import java.util.Map; +import org.apache.tiles.request.AbstractRequest; import org.apache.tiles.request.Request; import org.apache.tiles.request.render.Renderer; import org.junit.Before; @@ -36,6 +37,7 @@ import static org.mockito.BDDMockito.*; * Test fixture for {@link TilesView}. * * @author mick semb wever + * @author Sebastien Deleuze */ public class TilesViewTests { @@ -72,7 +74,7 @@ public class TilesViewTests { } @Test - public void testRender() throws Exception { + public void render() throws Exception { Map model = new HashMap(); model.put("modelAttribute", "modelValue"); view.render(model, request, response); @@ -80,4 +82,17 @@ public class TilesViewTests { verify(renderer).render(eq(VIEW_PATH), isA(Request.class)); } + @Test + public void alwaysIncludeDefaults() throws Exception { + view.render(new HashMap(), request, response); + assertNull(request.getAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME)); + } + + @Test + public void alwaysIncludeEnabled() throws Exception { + view.setAlwaysInclude(true); + view.render(new HashMap(), request, response); + assertTrue((Boolean)request.getAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME)); + } + }