diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java index 60a6dc2035c..a43c1aaf802 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java @@ -23,16 +23,16 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; import javax.servlet.ServletOutputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; @@ -44,6 +44,8 @@ import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.StringUtils; import org.springframework.web.util.WebUtils; +import static java.time.format.DateTimeFormatter.*; + /** * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface. * @@ -58,9 +60,7 @@ public class MockHttpServletResponse implements HttpServletResponse { private static final String CHARSET_PREFIX = "charset="; - private static final String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; - - private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + private static final ZoneId GMT = ZoneId.of("GMT"); //--------------------------------------------------------------------- @@ -508,12 +508,10 @@ public class MockHttpServletResponse implements HttpServletResponse { } public long getDateHeader(String name) { - SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US); - dateFormat.setTimeZone(GMT); try { - return dateFormat.parse(getHeader(name)).getTime(); + return ZonedDateTime.parse(getHeader(name), RFC_1123_DATE_TIME).toInstant().toEpochMilli(); } - catch (ParseException ex) { + catch (DateTimeParseException ex) { throw new IllegalArgumentException( "Value for header '" + name + "' is not a valid Date: " + getHeader(name)); } @@ -525,9 +523,9 @@ public class MockHttpServletResponse implements HttpServletResponse { } private String formatDate(long date) { - SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US); - dateFormat.setTimeZone(GMT); - return dateFormat.format(new Date(date)); + Instant instant = Instant.ofEpochMilli(date); + ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, GMT); + return RFC_1123_DATE_TIME.format(zonedDateTime); } @Override diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java index 0b9dee0c22a..c7e5b145800 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java @@ -16,11 +16,11 @@ package org.springframework.web.context.request; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Arrays; import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; import org.junit.Before; import org.junit.Test; @@ -32,6 +32,7 @@ import org.junit.runners.Parameterized.Parameters; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; +import static java.time.format.DateTimeFormatter.*; import static org.junit.Assert.*; /** @@ -43,9 +44,9 @@ import static org.junit.Assert.*; @RunWith(Parameterized.class) public class ServletWebRequestHttpMethodsTests { - private static final String CURRENT_TIME = "Wed, 09 Apr 2014 09:57:42 GMT"; + private static final ZoneId GMT = ZoneId.of("GMT"); - private SimpleDateFormat dateFormat; + private static final String CURRENT_TIME = "Wed, 9 Apr 2014 09:57:42 GMT"; private MockHttpServletRequest servletRequest; @@ -70,8 +71,6 @@ public class ServletWebRequestHttpMethodsTests { @Before public void setup() { currentDate = new Date(); - dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); - dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); servletRequest = new MockHttpServletRequest(method, "http://example.org"); servletResponse = new MockHttpServletResponse(); request = new ServletWebRequest(servletRequest, servletResponse); @@ -127,7 +126,7 @@ public class ServletWebRequestHttpMethodsTests { assertTrue(request.checkNotModified(epochTime)); assertEquals(304, servletResponse.getStatus()); - assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(epochTime).atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test @@ -138,7 +137,7 @@ public class ServletWebRequestHttpMethodsTests { assertFalse(request.checkNotModified(currentDate.getTime())); assertEquals(200, servletResponse.getStatus()); - assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(currentDate.toInstant().atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test @@ -221,7 +220,7 @@ public class ServletWebRequestHttpMethodsTests { assertEquals(304, servletResponse.getStatus()); assertEquals(eTag, servletResponse.getHeader("ETag")); - assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(currentDate.toInstant().atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test // SPR-14224 @@ -236,7 +235,7 @@ public class ServletWebRequestHttpMethodsTests { assertEquals(304, servletResponse.getStatus()); assertEquals(eTag, servletResponse.getHeader("ETag")); - assertEquals(dateFormat.format(currentEpoch), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(currentEpoch).atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test @@ -251,7 +250,7 @@ public class ServletWebRequestHttpMethodsTests { assertEquals(200, servletResponse.getStatus()); assertEquals(currentETag, servletResponse.getHeader("ETag")); - assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(epochTime).atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test @@ -291,26 +290,26 @@ public class ServletWebRequestHttpMethodsTests { @Test public void checkNotModifiedTimestampWithLengthPart() throws Exception { - long epochTime = dateFormat.parse(CURRENT_TIME).getTime(); + long epochTime = ZonedDateTime.parse(CURRENT_TIME, RFC_1123_DATE_TIME).toInstant().toEpochMilli(); servletRequest.setMethod("GET"); servletRequest.addHeader("If-Modified-Since", "Wed, 09 Apr 2014 09:57:42 GMT; length=13774"); assertTrue(request.checkNotModified(epochTime)); assertEquals(304, servletResponse.getStatus()); - assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(epochTime).atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test public void checkModifiedTimestampWithLengthPart() throws Exception { - long epochTime = dateFormat.parse(CURRENT_TIME).getTime(); + long epochTime = ZonedDateTime.parse(CURRENT_TIME, RFC_1123_DATE_TIME).toInstant().toEpochMilli(); servletRequest.setMethod("GET"); servletRequest.addHeader("If-Modified-Since", "Wed, 08 Apr 2014 09:57:42 GMT; length=13774"); assertFalse(request.checkNotModified(epochTime)); assertEquals(200, servletResponse.getStatus()); - assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + assertEquals(RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(epochTime).atZone(GMT)), servletResponse.getHeader("Last-Modified")); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java index 3959be09550..cbd4ca3b0d7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java @@ -178,7 +178,7 @@ public class DispatcherServletTests { MockHttpServletResponse response = new MockHttpServletResponse(); simpleDispatcherServlet.service(request, response); assertTrue("Not forwarded", response.getForwardedUrl() == null); - assertEquals("Wed, 01 Apr 2015 00:00:00 GMT", response.getHeader("Last-Modified")); + assertEquals("Wed, 1 Apr 2015 00:00:00 GMT", response.getHeader("Last-Modified")); } @Test @@ -208,7 +208,7 @@ public class DispatcherServletTests { assertTrue(request.getAttribute("test3") != null); assertTrue(request.getAttribute("test3x") != null); assertTrue(request.getAttribute("test3y") != null); - assertEquals("Wed, 01 Apr 2015 00:00:01 GMT", response.getHeader("Last-Modified")); + assertEquals("Wed, 1 Apr 2015 00:00:01 GMT", response.getHeader("Last-Modified")); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java index 22a79a5dc5d..1aeba811aac 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java @@ -19,13 +19,11 @@ package org.springframework.web.servlet.mvc.method.annotation; import java.lang.reflect.Method; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Locale; -import java.util.TimeZone; import org.junit.Before; import org.junit.Rule; @@ -54,6 +52,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.method.support.ModelAndViewContainer; +import static java.time.Instant.*; +import static java.time.format.DateTimeFormatter.*; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; import static org.springframework.web.servlet.HandlerMapping.*; @@ -70,11 +70,12 @@ import static org.springframework.web.servlet.HandlerMapping.*; */ public class HttpEntityMethodProcessorMockTests { + private static final ZoneId GMT = ZoneId.of("GMT"); + + @Rule public ExpectedException thrown = ExpectedException.none(); - private SimpleDateFormat dateFormat; - private HttpEntityMethodProcessor processor; private HttpMessageConverter stringHttpMessageConverter; @@ -113,8 +114,6 @@ public class HttpEntityMethodProcessorMockTests { @Before @SuppressWarnings("unchecked") public void setup() throws Exception { - dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); - dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); stringHttpMessageConverter = mock(HttpMessageConverter.class); given(stringHttpMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN)); @@ -350,7 +349,7 @@ public class HttpEntityMethodProcessorMockTests { public void shouldHandleLastModifiedWithHttp304() throws Exception { long currentTime = new Date().getTime(); long oneMinuteAgo = currentTime - (1000 * 60); - servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, dateFormat.format(currentTime)); + servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, RFC_1123_DATE_TIME.format(ofEpochMilli(currentTime).atZone(GMT))); ResponseEntity returnValue = ResponseEntity.ok().lastModified(oneMinuteAgo).body("body"); initStringMessageConversion(MediaType.TEXT_PLAIN); @@ -388,7 +387,7 @@ public class HttpEntityMethodProcessorMockTests { long currentTime = new Date().getTime(); long oneMinuteAgo = currentTime - (1000 * 60); String etagValue = "\"deadb33f8badf00d\""; - servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, dateFormat.format(currentTime)); + servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, RFC_1123_DATE_TIME.format(ofEpochMilli(currentTime).atZone(GMT))); servletRequest.addHeader(HttpHeaders.IF_NONE_MATCH, etagValue); ResponseEntity returnValue = ResponseEntity.ok().eTag(etagValue).lastModified(oneMinuteAgo).body("body"); @@ -418,7 +417,7 @@ public class HttpEntityMethodProcessorMockTests { long oneMinuteAgo = currentTime - (1000 * 60); String etagValue = "\"deadb33f8badf00d\""; String changedEtagValue = "\"changed-etag-value\""; - servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, dateFormat.format(currentTime)); + servletRequest.addHeader(HttpHeaders.IF_MODIFIED_SINCE, RFC_1123_DATE_TIME.format(ofEpochMilli(currentTime).atZone(GMT))); servletRequest.addHeader(HttpHeaders.IF_NONE_MATCH, etagValue); ResponseEntity returnValue = ResponseEntity.ok() .eTag(changedEtagValue).lastModified(oneMinuteAgo).body("body"); @@ -473,7 +472,7 @@ public class HttpEntityMethodProcessorMockTests { public void shouldHandleIfNoneMatchIfUnmodifiedSince() throws Exception { String etagValue = "\"some-etag\""; servletRequest.addHeader(HttpHeaders.IF_NONE_MATCH, etagValue); - servletRequest.addHeader(HttpHeaders.IF_UNMODIFIED_SINCE, dateFormat.format(new Date().getTime())); + servletRequest.addHeader(HttpHeaders.IF_UNMODIFIED_SINCE, RFC_1123_DATE_TIME.format(ofEpochMilli(new Date().getTime()).atZone(GMT))); ResponseEntity returnValue = ResponseEntity.ok().eTag(etagValue).body("body"); initStringMessageConversion(MediaType.TEXT_PLAIN); @@ -538,7 +537,7 @@ public class HttpEntityMethodProcessorMockTests { } if (lastModified != -1) { assertEquals(1, servletResponse.getHeaderValues(HttpHeaders.LAST_MODIFIED).size()); - assertEquals(dateFormat.format(lastModified), servletResponse.getHeader(HttpHeaders.LAST_MODIFIED)); + assertEquals(RFC_1123_DATE_TIME.format(ofEpochMilli(lastModified).atZone(GMT)), servletResponse.getHeader(HttpHeaders.LAST_MODIFIED)); } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index cd174d35fa0..9b1c6eea9d7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -17,13 +17,13 @@ package org.springframework.web.servlet.resource; import java.io.IOException; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Locale; -import java.util.TimeZone; import javax.servlet.http.HttpServletResponse; import org.hamcrest.Matchers; @@ -45,6 +45,7 @@ import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManagerFactoryBean; import org.springframework.web.servlet.HandlerMapping; +import static java.time.format.DateTimeFormatter.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; @@ -61,8 +62,6 @@ import static org.junit.Assert.fail; */ public class ResourceHttpRequestHandlerTests { - private SimpleDateFormat dateFormat; - private ResourceHttpRequestHandler handler; private MockHttpServletRequest request; @@ -72,8 +71,6 @@ public class ResourceHttpRequestHandlerTests { @Before public void setUp() throws Exception { - dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); - dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); List paths = new ArrayList<>(2); paths.add(new ClassPathResource("test/", getClass())); @@ -623,7 +620,7 @@ public class ResourceHttpRequestHandlerTests { private long dateHeaderAsLong(String responseHeaderName) throws Exception { - return dateFormat.parse(this.response.getHeader(responseHeaderName)).getTime(); + return ZonedDateTime.parse(this.response.getHeader(responseHeaderName), RFC_1123_DATE_TIME).toInstant().toEpochMilli(); } private long resourceLastModified(String resourceName) throws IOException { @@ -632,7 +629,7 @@ public class ResourceHttpRequestHandlerTests { private String resourceLastModifiedDate(String resourceName) throws IOException { long lastModified = new ClassPathResource(resourceName, getClass()).getFile().lastModified(); - return dateFormat.format(lastModified); + return RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(lastModified).atZone(ZoneId.of("GMT"))); }