diff --git a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java index 19d1f78305..8be9bfb93f 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java +++ b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2025 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. @@ -19,6 +19,7 @@ package org.springframework.mock.web.server; import org.jspecify.annotations.Nullable; import reactor.core.publisher.Mono; +import org.springframework.context.ApplicationContext; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.http.server.reactive.MockServerHttpResponse; @@ -39,9 +40,15 @@ import org.springframework.web.server.session.WebSessionManager; */ public final class MockServerWebExchange extends DefaultServerWebExchange { - private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) { - super(request, new MockServerHttpResponse(), sessionManager, - ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); + + private MockServerWebExchange( + MockServerHttpRequest request, @Nullable WebSessionManager sessionManager, + @Nullable ApplicationContext applicationContext) { + + super(request, new MockServerHttpResponse(), + sessionManager != null ? sessionManager : new DefaultWebSessionManager(), + ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver(), + applicationContext); } @@ -100,6 +107,9 @@ public final class MockServerWebExchange extends DefaultServerWebExchange { private @Nullable WebSessionManager sessionManager; + @Nullable + private ApplicationContext applicationContext; + public Builder(MockServerHttpRequest request) { this.request = request; } @@ -126,12 +136,21 @@ public final class MockServerWebExchange extends DefaultServerWebExchange { return this; } + /** + * Provide the {@code ApplicationContext} to expose through the exchange. + * @param applicationContext the context to use + * @since 6.2.5 + */ + public Builder applicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + return this; + } + /** * Build the {@code MockServerWebExchange} instance. */ public MockServerWebExchange build() { - return new MockServerWebExchange(this.request, - this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager()); + return new MockServerWebExchange(this.request, this.sessionManager, this.applicationContext); } } diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java index f6f7768dd7..59427a3592 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -287,14 +287,7 @@ public class CorsConfiguration { * allowCredentials} is set to {@code true}, that combination is handled * by copying the method specified in the CORS preflight request. *
If not set, only {@code "GET"} and {@code "HEAD"} are allowed. - *
By default this is not set. - *
Note: CORS checks use values from "Forwarded" - * (RFC 7239), - * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, - * if present, in order to reflect the client-originated address. - * Consider using the {@code ForwardedHeaderFilter} in order to choose from a - * central place whether to extract and use, or to discard such headers. - * See the Spring Framework reference for more on this filter. + *
By default, this is not set.
*/
public void setAllowedMethods(@Nullable List By default this is not set (i.e. user credentials are not supported).
+ * By default, this is not set (i.e. user credentials are not supported).
*/
public void setAllowCredentials(@Nullable Boolean allowCredentials) {
this.allowCredentials = allowCredentials;
@@ -466,7 +459,7 @@ public class CorsConfiguration {
* Setting this property has an impact on how {@link #setAllowedOrigins(List)
* origins} and {@link #setAllowedOriginPatterns(List) originPatterns} are processed,
* see related API documentation for more details.
- * By default this is not set (i.e. private network access is not supported).
+ * By default, this is not set (i.e. private network access is not supported).
* @since 5.3.32
* @see Private network access specifications
*/
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 a305e1a991..a3ec76997b 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -117,7 +117,7 @@ public class DefaultServerWebExchange implements ServerWebExchange {
this(request, response, sessionManager, codecConfigurer, localeContextResolver, null);
}
- DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
+ protected DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) {
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java
index 9f8f87b5e9..acba901ba5 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -171,7 +171,6 @@ final class SseServerResponse extends AbstractServerResponse {
@Override
public SseBuilder comment(String comment) {
- Assert.hasLength(comment, "Comment must not be empty");
String[] lines = comment.split("\n");
for (String line : lines) {
field("", line);
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java
index 88cca2755a..b37b592100 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -84,13 +84,12 @@ import org.springframework.web.util.pattern.PathPatternParser;
* {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}.
*
*
- * Note: This class uses values from "Forwarded"
- * (RFC 7239),
- * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
- * if present, in order to reflect the client-originated protocol and address.
- * Consider using the {@code ForwardedHeaderFilter} in order to choose from a
- * central place whether to extract and use, or to discard such headers.
- * See the Spring Framework reference for more on this filter.
+ * Note: As of 5.1, methods in this class do not extract
+ * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the
+ * client-originated address. Please, use
+ * {@link org.springframework.web.filter.ForwardedHeaderFilter
+ * ForwardedHeaderFilter}, or similar from the underlying server, to extract
+ * and use such headers, or to discard them.
*
* @author Oliver Gierke
* @author Rossen Stoyanchev
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java
index fc7ea6f9f1..2a2bf761e6 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -173,6 +173,26 @@ class SseServerResponseTests {
assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected);
}
+ @Test // gh-34608
+ void sendHeartbeat() throws Exception {
+ ServerResponse response = ServerResponse.sse(sse -> {
+ try {
+ sse.comment("").send();
+ }
+ catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ });
+
+ ServerResponse.Context context = Collections::emptyList;
+
+ ModelAndView mav = response.writeTo(this.mockRequest, this.mockResponse, context);
+ assertThat(mav).isNull();
+
+ String expected = ":\n\n";
+ assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected);
+ }
+
private static final class Person {