Improve HTTP caching flexiblity
This commit improves HTTP caching defaults and flexibility in
Spring MVC.
1) Better default caching headers
The `WebContentGenerator` abstract class has been updated with
better HTTP defaults for HTTP caching, in line with current
browsers and proxies implementation (wide support of HTTP1.1, etc);
depending on the `setCacheSeconds` value:
* sends "Cache-Control: max-age=xxx" for caching responses and
do not send a "must-revalidate" value by default.
* sends "Cache-Control: no-store" or "Cache-Control: no-cache"
in order to prevent caching
Other methods used to set specific header such as
`setUseExpiresHeader` or `setAlwaysMustRevalidate` are now deprecated
in favor of `setCacheControl` for better flexibility.
Using one of the deprecated methods re-enables previous HTTP caching
behavior.
This change is applied in many Handlers, since
`WebContentGenerator` is extended by `AbstractController`,
`WebContentInterceptor`, `ResourceHttpRequestHandler` and others.
2) New CacheControl builder class
This new class brings more flexibility and allows developers
to set custom HTTP caching headers.
Several strategies are provided:
* `CacheControl.maxAge(int)` for caching responses with a
"Cache-Control: max-age=xxx" header
* `CacheControl.noStore()` prevents responses from being cached
with a "Cache-Control: no-store" header
* `CacheControl.noCache()` forces caches to revalidate the cached
response before reusing it, with a "Cache-Control: no-store" header.
From that point, it is possible to chain method calls to craft a
custom CacheControl instance:
```
CacheControl cc = CacheControl.maxAge(1, TimeUnit.HOURS)
.cachePublic().noTransform();
```
3) Configuring HTTP caching in Resource Handlers
On top of the existing ways of configuring caching mechanisms,
it is now possible to use a custom `CacheControl` to serve
resources:
```
@Configuration
public class MyWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cc = CacheControl.maxAge(1, TimeUnit.HOURS);
registry.addResourceHandler("/resources/**)
.addResourceLocations("classpath:/resources/")
.setCacheControl(cc);
}
}
```
or
```
<mvc:resources mapping="/resources/**" location="classpath:/resources/">
<mvc:cachecontrol max-age="3600" cache-public="true"/>
</mvc:resources>
```
Issue: SPR-2779, SPR-6834, SPR-7129, SPR-9543, SPR-10464
This commit is contained in:
@@ -29,6 +29,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -73,6 +74,7 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
@@ -202,7 +204,7 @@ public class MvcNamespaceTests {
|
||||
assertTrue(converters.size() > 0);
|
||||
for (HttpMessageConverter<?> converter : converters) {
|
||||
if (converter instanceof AbstractJackson2HttpMessageConverter) {
|
||||
ObjectMapper objectMapper = ((AbstractJackson2HttpMessageConverter)converter).getObjectMapper();
|
||||
ObjectMapper objectMapper = ((AbstractJackson2HttpMessageConverter) converter).getObjectMapper();
|
||||
assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));
|
||||
assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));
|
||||
assertFalse(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
|
||||
@@ -233,7 +235,7 @@ public class MvcNamespaceTests {
|
||||
adapter.handle(request, response, handlerMethod);
|
||||
assertTrue(handler.recordedValidationError);
|
||||
assertEquals(LocalDate.parse("2009-10-31").toDate(), handler.date);
|
||||
assertEquals(Double.valueOf(0.9999),handler.percent);
|
||||
assertEquals(Double.valueOf(0.9999), handler.percent);
|
||||
|
||||
CompositeUriComponentsContributor uriComponentsContributor = this.appContext.getBean(
|
||||
MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME,
|
||||
@@ -242,7 +244,7 @@ public class MvcNamespaceTests {
|
||||
assertNotNull(uriComponentsContributor);
|
||||
}
|
||||
|
||||
@Test(expected=TypeMismatchException.class)
|
||||
@Test(expected = TypeMismatchException.class)
|
||||
public void testCustomConversionService() throws Exception {
|
||||
loadBeanDefinitions("mvc-config-custom-conversion-service.xml", 13);
|
||||
|
||||
@@ -384,10 +386,12 @@ public class MvcNamespaceTests {
|
||||
assertEquals(5, mapping.getOrder());
|
||||
assertNotNull(mapping.getUrlMap().get("/resources/**"));
|
||||
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String)mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String) mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler.class);
|
||||
assertNotNull(handler);
|
||||
assertEquals(3600, handler.getCacheSeconds());
|
||||
assertThat(handler.getCacheControl().getHeaderValue(),
|
||||
Matchers.equalTo(CacheControl.maxAge(1, TimeUnit.HOURS).getHeaderValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -397,7 +401,7 @@ public class MvcNamespaceTests {
|
||||
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||
assertNotNull(mapping);
|
||||
assertNotNull(mapping.getUrlMap().get("/resources/**"));
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String)mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String) mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler.class);
|
||||
assertNotNull(handler);
|
||||
|
||||
@@ -435,10 +439,14 @@ public class MvcNamespaceTests {
|
||||
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||
assertNotNull(mapping);
|
||||
assertNotNull(mapping.getUrlMap().get("/resources/**"));
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String)mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler handler = appContext.getBean((String) mapping.getUrlMap().get("/resources/**"),
|
||||
ResourceHttpRequestHandler.class);
|
||||
assertNotNull(handler);
|
||||
|
||||
assertThat(handler.getCacheControl().getHeaderValue(),
|
||||
Matchers.equalTo(CacheControl.maxAge(1, TimeUnit.HOURS)
|
||||
.sMaxAge(30, TimeUnit.MINUTES).cachePublic().getHeaderValue()));
|
||||
|
||||
List<ResourceResolver> resolvers = handler.getResourceResolvers();
|
||||
assertThat(resolvers, Matchers.hasSize(3));
|
||||
assertThat(resolvers.get(0), Matchers.instanceOf(VersionResourceResolver.class));
|
||||
@@ -762,12 +770,12 @@ public class MvcNamespaceTests {
|
||||
};
|
||||
accessor = new DirectFieldAccessor(tilesConfigurer);
|
||||
assertArrayEquals(definitions, (String[]) accessor.getPropertyValue("definitions"));
|
||||
assertTrue((boolean)accessor.getPropertyValue("checkRefresh"));
|
||||
assertTrue((boolean) accessor.getPropertyValue("checkRefresh"));
|
||||
|
||||
FreeMarkerConfigurer freeMarkerConfigurer = appContext.getBean(FreeMarkerConfigurer.class);
|
||||
assertNotNull(freeMarkerConfigurer);
|
||||
accessor = new DirectFieldAccessor(freeMarkerConfigurer);
|
||||
assertArrayEquals(new String[]{"/", "/test"}, (String[]) accessor.getPropertyValue("templateLoaderPaths"));
|
||||
assertArrayEquals(new String[] {"/", "/test"}, (String[]) accessor.getPropertyValue("templateLoaderPaths"));
|
||||
|
||||
VelocityConfigurer velocityConfigurer = appContext.getBean(VelocityConfigurer.class);
|
||||
assertNotNull(velocityConfigurer);
|
||||
@@ -846,7 +854,7 @@ public class MvcNamespaceTests {
|
||||
}
|
||||
|
||||
|
||||
@DateTimeFormat(iso=ISO.DATE)
|
||||
@DateTimeFormat(iso = ISO.DATE)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IsoDate {
|
||||
@@ -868,7 +876,9 @@ public class MvcNamespaceTests {
|
||||
public static class TestController {
|
||||
|
||||
private Date date;
|
||||
|
||||
private Double percent;
|
||||
|
||||
private boolean recordedValidationError;
|
||||
|
||||
@RequestMapping
|
||||
@@ -900,7 +910,7 @@ public class MvcNamespaceTests {
|
||||
|
||||
private static class TestBean {
|
||||
|
||||
@NotNull(groups=MyGroup.class)
|
||||
@NotNull(groups = MyGroup.class)
|
||||
private String field;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -920,7 +930,8 @@ public class MvcNamespaceTests {
|
||||
public RequestDispatcher getNamedDispatcher(String path) {
|
||||
if (path.equals("default") || path.equals("custom")) {
|
||||
return new MockRequestDispatcher("/");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
@@ -88,6 +89,18 @@ public class ResourceHandlerRegistryTests {
|
||||
|
||||
this.registration.setCachePeriod(0);
|
||||
assertEquals(0, getHandler("/resources/**").getCacheSeconds());
|
||||
assertThat(getHandler("/resources/**").getCacheControl().getHeaderValue(),
|
||||
Matchers.equalTo(CacheControl.noStore().getHeaderValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheControl() {
|
||||
assertThat(getHandler("/resources/**").getCacheControl(),
|
||||
Matchers.nullValue());
|
||||
|
||||
this.registration.setCacheControl(CacheControl.noCache().cachePrivate());
|
||||
assertThat(getHandler("/resources/**").getCacheControl().getHeaderValue(),
|
||||
Matchers.equalTo(CacheControl.noCache().cachePrivate().getHeaderValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -53,9 +53,6 @@ public class WebContentInterceptorTests {
|
||||
|
||||
interceptor.preHandle(request, response, null);
|
||||
|
||||
List expiresHeaders = response.getHeaders("Expires");
|
||||
assertNotNull("'Expires' header not set (must be) : null", expiresHeaders);
|
||||
assertTrue("'Expires' header not set (must be) : empty", expiresHeaders.size() > 0);
|
||||
List cacheControlHeaders = response.getHeaders("Cache-Control");
|
||||
assertNotNull("'Cache-Control' header not set (must be) : null", cacheControlHeaders);
|
||||
assertTrue("'Cache-Control' header not set (must be) : empty", cacheControlHeaders.size() > 0);
|
||||
@@ -73,17 +70,12 @@ public class WebContentInterceptorTests {
|
||||
request.setRequestURI("http://localhost:7070/example/adminhandle.vm");
|
||||
interceptor.preHandle(request, response, null);
|
||||
|
||||
List expiresHeaders = response.getHeaders("Expires");
|
||||
assertSame("'Expires' header set (must not be) : empty", 0, expiresHeaders.size());
|
||||
List cacheControlHeaders = response.getHeaders("Cache-Control");
|
||||
assertSame("'Cache-Control' header set (must not be) : empty", 0, cacheControlHeaders.size());
|
||||
assertSame("'Cache-Control' header set must be empty", 0, cacheControlHeaders.size());
|
||||
|
||||
request.setRequestURI("http://localhost:7070/example/bingo.html");
|
||||
interceptor.preHandle(request, response, null);
|
||||
|
||||
expiresHeaders = response.getHeaders("Expires");
|
||||
assertNotNull("'Expires' header not set (must be) : null", expiresHeaders);
|
||||
assertTrue("'Expires' header not set (must be) : empty", expiresHeaders.size() > 0);
|
||||
cacheControlHeaders = response.getHeaders("Cache-Control");
|
||||
assertNotNull("'Cache-Control' header not set (must be) : null", cacheControlHeaders);
|
||||
assertTrue("'Cache-Control' header not set (must be) : empty", cacheControlHeaders.size() > 0);
|
||||
@@ -96,9 +88,6 @@ public class WebContentInterceptorTests {
|
||||
|
||||
interceptor.preHandle(request, response, null);
|
||||
|
||||
List expiresHeaders = response.getHeaders("Expires");
|
||||
assertNotNull("'Expires' header not set (must be) : null", expiresHeaders);
|
||||
assertTrue("'Expires' header not set (must be) : empty", expiresHeaders.size() > 0);
|
||||
List cacheControlHeaders = response.getHeaders("Cache-Control");
|
||||
assertNotNull("'Cache-Control' header not set (must be) : null", cacheControlHeaders);
|
||||
assertTrue("'Cache-Control' header not set (must be) : empty", cacheControlHeaders.size() > 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -118,7 +118,7 @@ public class RequestMappingHandlerAdapterTests {
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
|
||||
this.handlerAdapter.handle(this.request, this.response, handlerMethod(handler, "handle"));
|
||||
assertEquals("no-cache", this.response.getHeader("Cache-Control"));
|
||||
assertEquals("no-store", this.response.getHeader("Cache-Control"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package org.springframework.web.servlet.resource;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -75,21 +78,62 @@ public class ResourceHttpRequestHandlerTests {
|
||||
|
||||
assertEquals("text/css", this.response.getContentType());
|
||||
assertEquals(17, this.response.getContentLength());
|
||||
assertTrue(headerAsLong("Expires") >= System.currentTimeMillis() - 1000 + (3600 * 1000));
|
||||
assertEquals("max-age=3600, must-revalidate", this.response.getHeader("Cache-Control"));
|
||||
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("test/foo.css"));
|
||||
assertEquals("h1 { color:red; }", this.response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceNoCache() throws Exception {
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
|
||||
this.handler.setCacheSeconds(0);
|
||||
this.handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertEquals("no-store", this.response.getHeader("Cache-Control"));
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("test/foo.css"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void getResourcePreviousBehaviorCache() throws Exception {
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
|
||||
this.handler.setCacheSeconds(3600);
|
||||
this.handler.setUseExpiresHeader(true);
|
||||
this.handler.setUseCacheControlHeader(true);
|
||||
this.handler.setAlwaysMustRevalidate(true);
|
||||
this.handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertEquals("max-age=3600, must-revalidate", this.response.getHeader("Cache-Control"));
|
||||
assertTrue(headerAsLong("Expires") >= System.currentTimeMillis() - 1000 + (3600 * 1000));
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("test/foo.css"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void getResourcePreviousBehaviorNoCache() throws Exception {
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
|
||||
this.handler.setCacheSeconds(0);
|
||||
this.handler.setUseCacheControlNoStore(true);
|
||||
this.handler.setUseCacheControlHeader(true);
|
||||
this.handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertEquals("no-cache", this.response.getHeader("Pragma"));
|
||||
assertThat(this.response.getHeaderValues("Cache-Control"), Matchers.contains("no-cache", "no-store"));
|
||||
assertTrue(headerAsLong("Expires") == 1);
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("test/foo.css"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceWithHtmlMediaType() throws Exception {
|
||||
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.html");
|
||||
this.handler.handleRequest(this.request, this.response);
|
||||
|
||||
assertEquals("text/html", this.response.getContentType());
|
||||
assertTrue(headerAsLong("Expires") >= System.currentTimeMillis() - 1000 + (3600 * 1000));
|
||||
assertEquals("max-age=3600, must-revalidate", this.response.getHeader("Cache-Control"));
|
||||
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("test/foo.html"));
|
||||
}
|
||||
@@ -101,8 +145,7 @@ public class ResourceHttpRequestHandlerTests {
|
||||
|
||||
assertEquals("text/css", this.response.getContentType());
|
||||
assertEquals(17, this.response.getContentLength());
|
||||
assertTrue(headerAsLong("Expires") >= System.currentTimeMillis() - 1000 + (3600 * 1000));
|
||||
assertEquals("max-age=3600, must-revalidate", this.response.getHeader("Cache-Control"));
|
||||
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
|
||||
assertTrue(this.response.containsHeader("Last-Modified"));
|
||||
assertEquals(headerAsLong("Last-Modified"), resourceLastModified("testalternatepath/baz.css"));
|
||||
assertEquals("h1 { color:red; }", this.response.getContentAsString());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -97,9 +97,7 @@ public class MappingJackson2JsonViewTests {
|
||||
view.setUpdateContentLength(true);
|
||||
view.render(model, request, response);
|
||||
|
||||
assertEquals("no-cache", response.getHeader("Pragma"));
|
||||
assertEquals("no-cache, no-store, max-age=0", response.getHeader("Cache-Control"));
|
||||
assertNotNull(response.getHeader("Expires"));
|
||||
assertEquals("no-store", response.getHeader("Cache-Control"));
|
||||
|
||||
assertEquals(MappingJackson2JsonView.DEFAULT_CONTENT_TYPE, response.getContentType());
|
||||
|
||||
@@ -134,9 +132,7 @@ public class MappingJackson2JsonViewTests {
|
||||
|
||||
view.render(model, request, response);
|
||||
|
||||
assertNull(response.getHeader("Pragma"));
|
||||
assertNull(response.getHeader("Cache-Control"));
|
||||
assertNull(response.getHeader("Expires"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -90,9 +90,7 @@ public class MappingJackson2XmlViewTests {
|
||||
view.setUpdateContentLength(true);
|
||||
view.render(model, request, response);
|
||||
|
||||
assertEquals("no-cache", response.getHeader("Pragma"));
|
||||
assertEquals("no-cache, no-store, max-age=0", response.getHeader("Cache-Control"));
|
||||
assertNotNull(response.getHeader("Expires"));
|
||||
assertEquals("no-store", response.getHeader("Cache-Control"));
|
||||
|
||||
assertEquals(MappingJackson2XmlView.DEFAULT_CONTENT_TYPE, response.getContentType());
|
||||
|
||||
@@ -127,9 +125,7 @@ public class MappingJackson2XmlViewTests {
|
||||
|
||||
view.render(model, request, response);
|
||||
|
||||
assertNull(response.getHeader("Pragma"));
|
||||
assertNull(response.getHeader("Cache-Control"));
|
||||
assertNull(response.getHeader("Expires"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user