From 068151925503e6124eb85158d137779e925f4a38 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 1 Sep 2016 18:07:23 -0400 Subject: [PATCH] Add checkNotModified support for view resolution Issue: SPR-14522 --- .../view/ViewResolutionResultHandler.java | 3 ++ ...bstractRequestMappingIntegrationTests.java | 4 +++ ...MappingViewResolutionIntegrationTests.java | 29 +++++++++++++++++-- .../web/server/ServerWebExchange.java | 6 ++++ .../adapter/DefaultServerWebExchange.java | 5 ++++ 5 files changed, 45 insertions(+), 2 deletions(-) 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 ab6681b1e0..b9c1e40015 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 @@ -230,6 +230,9 @@ public class ViewResolutionResultHandler extends ContentNegotiatingResultHandler } private Mono getDefaultViewNameMono(ServerWebExchange exchange, HandlerResult result) { + if (exchange.isNotModified()) { + return Mono.empty(); + } String defaultViewName = getDefaultViewName(result, exchange); if (defaultViewName != null) { return Mono.just(defaultViewName); diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/AbstractRequestMappingIntegrationTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/AbstractRequestMappingIntegrationTests.java index b3847bc365..1d79704359 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/AbstractRequestMappingIntegrationTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/AbstractRequestMappingIntegrationTests.java @@ -56,6 +56,10 @@ public abstract class AbstractRequestMappingIntegrationTests extends AbstractHtt return this.applicationContext; } + RestTemplate getRestTemplate() { + return this.restTemplate; + } + ResponseEntity performGet(String url, MediaType out, Class type) throws Exception { diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingViewResolutionIntegrationTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingViewResolutionIntegrationTests.java index 9ea276300a..53090071a6 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingViewResolutionIntegrationTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingViewResolutionIntegrationTests.java @@ -16,6 +16,9 @@ package org.springframework.web.reactive.result.method.annotation; +import java.net.URI; +import java.util.Optional; + import org.junit.Test; import org.springframework.context.ApplicationContext; @@ -23,7 +26,10 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -31,8 +37,11 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.reactive.config.ViewResolverRegistry; import org.springframework.web.reactive.config.WebReactiveConfiguration; import org.springframework.web.reactive.result.view.freemarker.FreeMarkerConfigurer; +import org.springframework.web.server.ServerWebExchange; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.springframework.http.RequestEntity.get; /** @@ -58,6 +67,16 @@ public class RequestMappingViewResolutionIntegrationTests extends AbstractReques assertEquals(expected, performGet("/html?name=Jason", MediaType.TEXT_HTML, String.class).getBody()); } + @Test + public void etagCheckWithNotModifiedResponse() throws Exception { + URI uri = new URI("http://localhost:" + this.port + "/html"); + RequestEntity request = get(uri).ifNoneMatch("\"deadb33f8badf00d\"").build(); + ResponseEntity response = getRestTemplate().exchange(request, String.class); + + assertEquals(HttpStatus.NOT_MODIFIED, response.getStatusCode()); + assertNull(response.getBody()); + } + @Configuration @ComponentScan(resourcePattern = "**/RequestMappingViewResolutionIntegrationTests$*.class") @@ -84,10 +103,16 @@ public class RequestMappingViewResolutionIntegrationTests extends AbstractReques private static class TestController { @GetMapping("/html") - public String getHtmlPage(@RequestParam String name, Model model) { - model.addAttribute("hello", "Hello: " + name + "!"); + public String getHtmlPage(@RequestParam Optional name, Model model, + ServerWebExchange exchange) { + + if (exchange.checkNotModified("deadb33f8badf00d")) { + return null; + } + model.addAttribute("hello", "Hello: " + name.orElse("") + "!"); return "test"; } + } } diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java index e865f22718..5789bcebed 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java @@ -68,6 +68,12 @@ public interface ServerWebExchange { */ Mono getSession(); + /** + * Returns {@code true} if the one of the {@code checkNotModified} methods + * in this contract were used and they returned true. + */ + boolean isNotModified(); + /** * An overloaded variant of {@link #checkNotModified(String, Instant)} with * a last-modified timestamp only. diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java index 568f526a3f..af75fea7e5 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java @@ -104,6 +104,11 @@ public class DefaultServerWebExchange implements ServerWebExchange { return this.sessionMono; } + @Override + public boolean isNotModified() { + return this.notModified; + } + @Override public boolean checkNotModified(Instant lastModified) { return checkNotModified(null, lastModified);