From ad5710c1d1180edfb425c07f908d53e34bb109de Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 13:14:47 +0200 Subject: [PATCH 1/6] Restore original readOnlyHttpHeaders signature for binary compatibility Closes gh-25034 --- .../org/springframework/http/HttpHeaders.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index ff1e9b0cbd9..6a6f9db9db3 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -385,7 +385,7 @@ public class HttpHeaders implements MultiValueMap, Serializable * An empty {@code HttpHeaders} instance (immutable). * @since 5.0 */ - public static final HttpHeaders EMPTY = new ReadOnlyHttpHeaders(new HttpHeaders(new LinkedMultiValueMap<>(0))); + public static final HttpHeaders EMPTY = new ReadOnlyHttpHeaders(new LinkedMultiValueMap<>()); /** * Pattern matching ETag multiple field values in headers such as "If-Match", "If-None-Match". @@ -1769,17 +1769,21 @@ public class HttpHeaders implements MultiValueMap, Serializable /** - * Apply a read-only {@code HttpHeaders} wrapper around the given headers. + * Apply a read-only {@code HttpHeaders} wrapper around the given headers, + * if necessary. + * @param headers the headers to expose + * @return a read-only variant of the headers, or the original headers as-is */ - public static HttpHeaders readOnlyHttpHeaders(MultiValueMap headers) { + public static HttpHeaders readOnlyHttpHeaders(HttpHeaders headers) { Assert.notNull(headers, "HttpHeaders must not be null"); - return (headers instanceof ReadOnlyHttpHeaders ? - (HttpHeaders) headers : new ReadOnlyHttpHeaders(headers)); + return (headers instanceof ReadOnlyHttpHeaders ? headers : new ReadOnlyHttpHeaders(headers.headers)); } /** * Remove any read-only wrapper that may have been previously applied around - * the given headers via {@link #readOnlyHttpHeaders(MultiValueMap)}. + * the given headers via {@link #readOnlyHttpHeaders(HttpHeaders)}. + * @param headers the headers to expose + * @return a writable variant of the headers, or the original headers as-is * @since 5.1.1 */ public static HttpHeaders writableHttpHeaders(HttpHeaders headers) { From 196bb6fe322adc51020080a89e96182202cd0858 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 13:21:20 +0200 Subject: [PATCH 2/6] Support for shared GroovyClassLoader in GroovyScriptFactory Exposes setClassLoader method in ConfigurableApplicationContext interface as obvious first-class configuration option. Closes gh-25177 --- .../context/ConfigurableApplicationContext.java | 11 ++++++++++- .../scripting/groovy/GroovyScriptFactory.java | 11 +++++++++-- src/docs/asciidoc/languages/dynamic-languages.adoc | 14 ++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java index 2038e662ca6..5a31673e512 100644 --- a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -147,6 +147,15 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life */ void addApplicationListener(ApplicationListener listener); + /** + * Specify the ClassLoader to load class path resources and bean classes with. + *

This context class loader will be passed to the internal bean factory. + * @since 5.2.7 + * @see org.springframework.core.io.DefaultResourceLoader#DefaultResourceLoader(ClassLoader) + * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#setBeanClassLoader + */ + void setClassLoader(ClassLoader classLoader); + /** * Register the given protocol resolver with this application context, * allowing for additional resource protocols to be handled. diff --git a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java index 9e2871bf0f5..90f812e08df 100644 --- a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java +++ b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 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. @@ -158,7 +158,14 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea @Override public void setBeanClassLoader(ClassLoader classLoader) { - this.groovyClassLoader = buildGroovyClassLoader(classLoader); + if (classLoader instanceof GroovyClassLoader && + (this.compilerConfiguration == null || + ((GroovyClassLoader) classLoader).hasCompatibleConfiguration(this.compilerConfiguration))) { + this.groovyClassLoader = (GroovyClassLoader) classLoader; + } + else { + this.groovyClassLoader = buildGroovyClassLoader(classLoader); + } } /** diff --git a/src/docs/asciidoc/languages/dynamic-languages.adoc b/src/docs/asciidoc/languages/dynamic-languages.adoc index cae5239b060..b255356df28 100644 --- a/src/docs/asciidoc/languages/dynamic-languages.adoc +++ b/src/docs/asciidoc/languages/dynamic-languages.adoc @@ -159,9 +159,8 @@ The steps involved in using dynamic-language-backed beans are as follows: element in the XML configuration (you can define such beans programmatically by using the Spring API, although you will have to consult the source code for directions on how to do this, as this chapter does not cover this type of advanced configuration). - Note that this is an iterative step. You need at least one bean - definition for each dynamic language source file (although multiple bean definitions can reference the same dynamic language source - file). + Note that this is an iterative step. You need at least one bean definition for each dynamic + language source file (although multiple bean definitions can reference the same source file). The first two steps (testing and writing your dynamic language source files) are beyond the scope of this chapter. See the language specification and reference manual @@ -578,9 +577,12 @@ If you do not use the Spring namespace support, you can still use the ---- -NOTE: As of Spring Framework 4.3.3, you may also specify a Groovy `CompilationCustomizer` -(such as an `ImportCustomizer`) or even a full Groovy `CompilerConfiguration` object -in the same place as Spring's `GroovyObjectCustomizer`. +NOTE: You may also specify a Groovy `CompilationCustomizer` (such as an `ImportCustomizer`) +or even a full Groovy `CompilerConfiguration` object in the same place as Spring's +`GroovyObjectCustomizer`. Furthermore, you may set a common `GroovyClassLoader` with custom +configuration for your beans at the `ConfigurableApplicationContext.setClassLoader` level; +this also leads to shared `GroovyClassLoader` usage and is therefore recommendable in case of +a large number of scripted beans (avoiding an isolated `GroovyClassLoader` instance per bean). From d14140da69a98e11a11f241718bb0df2acb8afbc Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 13:21:46 +0200 Subject: [PATCH 3/6] Polishing --- .../ReflectiveAspectJAdvisorFactory.java | 5 ++-- .../AspectJPrecedenceComparator.java | 12 +++------ .../DelegatingWebFluxConfiguration.java | 5 +++- .../config/WebFluxConfigurationSupport.java | 25 +++++++++++-------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java index 2f3896e90c3..db6898f3102 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java @@ -76,9 +76,8 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto new InstanceComparator<>( Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class), (Converter) method -> { - AspectJAnnotation annotation = - AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method); - return (annotation != null ? annotation.getAnnotation() : null); + AspectJAnnotation ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method); + return (ann != null ? ann.getAnnotation() : null); }); Comparator methodNameComparator = new ConvertingComparator<>(Method::getName); METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator); diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/autoproxy/AspectJPrecedenceComparator.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/autoproxy/AspectJPrecedenceComparator.java index 64066f7c04e..d013cda2c98 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/autoproxy/AspectJPrecedenceComparator.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/autoproxy/AspectJPrecedenceComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 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. @@ -138,14 +138,8 @@ class AspectJPrecedenceComparator implements Comparator { } private int getAspectDeclarationOrder(Advisor anAdvisor) { - AspectJPrecedenceInformation precedenceInfo = - AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor); - if (precedenceInfo != null) { - return precedenceInfo.getDeclarationOrder(); - } - else { - return 0; - } + AspectJPrecedenceInformation precedenceInfo = AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor); + return (precedenceInfo != null ? precedenceInfo.getDeclarationOrder() : 0); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java index 1374cc4f05f..9f4e147359e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -42,6 +42,7 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport private final WebFluxConfigurerComposite configurers = new WebFluxConfigurerComposite(); + @Autowired(required = false) public void setConfigurers(List configurers) { if (!CollectionUtils.isEmpty(configurers)) { @@ -49,6 +50,7 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport } } + @Override protected void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) { this.configurers.configureContentTypeResolver(builder); @@ -100,4 +102,5 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport protected void configureViewResolvers(ViewResolverRegistry registry) { this.configurers.configureViewResolvers(registry); } + } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java index f2f40e8ea50..02283d1eb16 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -93,10 +93,6 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @Nullable private ApplicationContext applicationContext; - @Nullable - public final ApplicationContext getApplicationContext() { - return this.applicationContext; - } @Override public void setApplicationContext(@Nullable ApplicationContext applicationContext) { @@ -108,6 +104,12 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { } } + @Nullable + public final ApplicationContext getApplicationContext() { + return this.applicationContext; + } + + @Bean public DispatcherHandler webHandler() { return new DispatcherHandler(); @@ -122,6 +124,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @Bean public RequestMappingHandlerMapping requestMappingHandlerMapping( @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) { + RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping(); mapping.setOrder(0); mapping.setContentTypeResolver(contentTypeResolver); @@ -205,7 +208,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @Bean public RouterFunctionMapping routerFunctionMapping(ServerCodecConfigurer serverCodecConfigurer) { RouterFunctionMapping mapping = createRouterFunctionMapping(); - mapping.setOrder(-1); // go before RequestMappingHandlerMapping + mapping.setOrder(-1); // go before RequestMappingHandlerMapping mapping.setMessageReaders(serverCodecConfigurer.getReaders()); mapping.setCorsConfigurations(getCorsConfigurations()); @@ -330,8 +333,8 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { * initializing all {@link WebDataBinder} instances. */ protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer( - FormattingConversionService webFluxConversionService, - Validator webFluxValidator) { + FormattingConversionService webFluxConversionService, Validator webFluxValidator) { + ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(webFluxConversionService); initializer.setValidator(webFluxValidator); @@ -430,6 +433,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry, ServerCodecConfigurer serverCodecConfigurer, @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) { + return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(), contentTypeResolver, reactiveAdapterRegistry); } @@ -439,6 +443,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry, ServerCodecConfigurer serverCodecConfigurer, @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) { + return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(), contentTypeResolver, reactiveAdapterRegistry); } @@ -447,6 +452,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { public ViewResolutionResultHandler viewResolutionResultHandler( @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry, @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) { + ViewResolverRegistry registry = getViewResolverRegistry(); List resolvers = registry.getViewResolvers(); ViewResolutionResultHandler handler = new ViewResolutionResultHandler( @@ -457,8 +463,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { } @Bean - public ServerResponseResultHandler serverResponseResultHandler( - ServerCodecConfigurer serverCodecConfigurer) { + public ServerResponseResultHandler serverResponseResultHandler(ServerCodecConfigurer serverCodecConfigurer) { List resolvers = getViewResolverRegistry().getViewResolvers(); ServerResponseResultHandler handler = new ServerResponseResultHandler(); handler.setMessageWriters(serverCodecConfigurer.getWriters()); From 7b7d0a353dfb723fe883ee39cb25911546e6cbb4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 13:22:55 +0200 Subject: [PATCH 4/6] Upgrade to Hibernate ORM 5.4.17 and Checkstyle 8.33 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d89a934dc4b..4bbb3433593 100644 --- a/build.gradle +++ b/build.gradle @@ -115,7 +115,7 @@ configure(allprojects) { project -> dependency "net.sf.ehcache:ehcache:2.10.6" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core:5.4.16.Final" + dependency "org.hibernate:hibernate-core:5.4.17.Final" dependency "org.hibernate:hibernate-validator:6.1.5.Final" dependency "org.webjars:webjars-locator-core:0.45" dependency "org.webjars:underscorejs:1.8.3" @@ -325,7 +325,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.32" + toolVersion = "8.33" configDir = rootProject.file("src/checkstyle") } From 9cd9a8e86b459c5af647b9565e55ff43b1a0b6d8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 14:41:06 +0200 Subject: [PATCH 5/6] Extend readOnlyWebSocketHttpHeaders deprecation to 5.1.16 --- .../org/springframework/web/socket/WebSocketHttpHeaders.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java index e9854355698..84a3503bfc9 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java @@ -26,7 +26,6 @@ import java.util.Set; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; -import org.springframework.util.MultiValueMap; /** * An {@link org.springframework.http.HttpHeaders} variant that adds support for @@ -71,7 +70,8 @@ public class WebSocketHttpHeaders extends HttpHeaders { /** * Returns {@code WebSocketHttpHeaders} object that can only be read, not written to. - * @deprecated as of 5.2.7 in favor of {@link HttpHeaders#readOnlyHttpHeaders(MultiValueMap)} + * @deprecated as of 5.1.16, in favor of calling {@link #WebSocketHttpHeaders(HttpHeaders)} + * with a read-only wrapper from {@link HttpHeaders#readOnlyHttpHeaders(HttpHeaders)} */ @Deprecated public static WebSocketHttpHeaders readOnlyWebSocketHttpHeaders(WebSocketHttpHeaders headers) { From f3d4df2fd4e9d2c015ced1f5c749ce43391db017 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 6 Jun 2020 15:15:16 +0200 Subject: [PATCH 6/6] Consistently check available local/remote addresses for non-null --- .../reactive/MockServerHttpRequest.java | 20 +++++++++---------- .../DefaultServerHttpRequestBuilder.java | 14 ++++++------- .../reactive/ReactorServerHttpRequest.java | 11 ++++++---- .../server/reactive/ServerHttpRequest.java | 12 +++++------ .../reactive/ServerHttpRequestDecorator.java | 14 +++++++------ .../reactive/ServletServerHttpRequest.java | 13 +++++++----- .../reactive/UndertowServerHttpRequest.java | 12 ++++++----- .../reactive/MockServerHttpRequest.java | 20 +++++++++---------- 8 files changed, 63 insertions(+), 53 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java index 90eeb86054d..2488bdfc036 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Optional; import org.reactivestreams.Publisher; @@ -64,10 +65,10 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private final MultiValueMap cookies; @Nullable - private final InetSocketAddress remoteAddress; + private final InetSocketAddress localAddress; @Nullable - private final InetSocketAddress localAddress; + private final InetSocketAddress remoteAddress; @Nullable private final SslInfo sslInfo; @@ -98,25 +99,24 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override - @SuppressWarnings("ConstantConditions") public String getMethodValue() { - return (this.httpMethod != null ? this.httpMethod.name() : this.customHttpMethod); + return (this.httpMethod != null ? this.httpMethod.name() : Objects.requireNonNull(this.customHttpMethod)); } @Override @Nullable - public InetSocketAddress getRemoteAddress() { - return this.remoteAddress; - } - - @Nullable - @Override public InetSocketAddress getLocalAddress() { return this.localAddress; } + @Override @Nullable + public InetSocketAddress getRemoteAddress() { + return this.remoteAddress; + } + @Override + @Nullable protected SslInfo initSslInfo() { return this.sslInfo; } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java index ce5a3d2b373..bc05a9da1a8 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -211,20 +211,20 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder { return this.cookies; } - @Nullable @Override - public InetSocketAddress getRemoteAddress() { - return this.originalRequest.getRemoteAddress(); - } - @Nullable - @Override public InetSocketAddress getLocalAddress() { return this.originalRequest.getLocalAddress(); } + @Override @Nullable + public InetSocketAddress getRemoteAddress() { + return this.originalRequest.getRemoteAddress(); + } + @Override + @Nullable protected SslInfo initSslInfo() { return this.sslInfo; } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java index 9cd57c08c09..21e019fed4b 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java @@ -96,6 +96,7 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest { } else { InetSocketAddress localAddress = request.hostAddress(); + Assert.state(localAddress != null, "No host address available"); return new URI(scheme, null, localAddress.getHostString(), localAddress.getPort(), null, null, null); } @@ -151,13 +152,15 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest { } @Override - public InetSocketAddress getRemoteAddress() { - return this.request.remoteAddress(); + @Nullable + public InetSocketAddress getLocalAddress() { + return this.request.hostAddress(); } @Override - public InetSocketAddress getLocalAddress() { - return this.request.hostAddress(); + @Nullable + public InetSocketAddress getRemoteAddress() { + return this.request.remoteAddress(); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java index fd866d13503..a7673c3f472 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -65,19 +65,19 @@ public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage MultiValueMap getCookies(); /** - * Return the remote address where this request is connected to, if available. + * Return the local address the request was accepted on, if available. + * @since 5.2.3 */ @Nullable - default InetSocketAddress getRemoteAddress() { + default InetSocketAddress getLocalAddress() { return null; } /** - * Return the local address the request was accepted on, if available. - * 5.2.3 + * Return the remote address where this request is connected to, if available. */ @Nullable - default InetSocketAddress getLocalAddress() { + default InetSocketAddress getRemoteAddress() { return null; } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java index a526108d463..b75e3f12fb1 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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,17 +97,19 @@ public class ServerHttpRequestDecorator implements ServerHttpRequest { } @Override - public InetSocketAddress getRemoteAddress() { - return getDelegate().getRemoteAddress(); - } - - @Override + @Nullable public InetSocketAddress getLocalAddress() { return getDelegate().getLocalAddress(); } + @Override @Nullable + public InetSocketAddress getRemoteAddress() { + return getDelegate().getRemoteAddress(); + } + @Override + @Nullable public SslInfo getSslInfo() { return getDelegate().getSslInfo(); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index 6ea6e9404d6..e235826d67d 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -42,6 +42,7 @@ import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.HttpCookie; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; @@ -174,13 +175,15 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest { } @Override - public InetSocketAddress getRemoteAddress() { - return new InetSocketAddress(this.request.getRemoteHost(), this.request.getRemotePort()); + @NonNull + public InetSocketAddress getLocalAddress() { + return new InetSocketAddress(this.request.getLocalAddr(), this.request.getLocalPort()); } @Override - public InetSocketAddress getLocalAddress() { - return new InetSocketAddress(this.request.getLocalAddr(), this.request.getLocalPort()); + @NonNull + public InetSocketAddress getRemoteAddress() { + return new InetSocketAddress(this.request.getRemoteHost(), this.request.getRemotePort()); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java index 11b4418951f..6f6c4257ece 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -98,13 +98,15 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest { } @Override - public InetSocketAddress getRemoteAddress() { - return this.exchange.getSourceAddress(); + @Nullable + public InetSocketAddress getLocalAddress() { + return this.exchange.getDestinationAddress(); } @Override - public InetSocketAddress getLocalAddress() { - return this.exchange.getDestinationAddress(); + @Nullable + public InetSocketAddress getRemoteAddress() { + return this.exchange.getSourceAddress(); } @Nullable diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java index 9a468cb9937..4f0ab79882b 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Optional; import org.reactivestreams.Publisher; @@ -64,10 +65,10 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private final MultiValueMap cookies; @Nullable - private final InetSocketAddress remoteAddress; + private final InetSocketAddress localAddress; @Nullable - private final InetSocketAddress localAddress; + private final InetSocketAddress remoteAddress; @Nullable private final SslInfo sslInfo; @@ -98,25 +99,24 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override - @SuppressWarnings("ConstantConditions") public String getMethodValue() { - return (this.httpMethod != null ? this.httpMethod.name() : this.customHttpMethod); + return (this.httpMethod != null ? this.httpMethod.name() : Objects.requireNonNull(this.customHttpMethod)); } @Override @Nullable - public InetSocketAddress getRemoteAddress() { - return this.remoteAddress; - } - - @Nullable - @Override public InetSocketAddress getLocalAddress() { return this.localAddress; } + @Override @Nullable + public InetSocketAddress getRemoteAddress() { + return this.remoteAddress; + } + @Override + @Nullable protected SslInfo initSslInfo() { return this.sslInfo; }