From 4be41e9e266f45d7502127d9cb3bbd3e5388a3be Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 25 Feb 2019 17:18:07 +0100 Subject: [PATCH 1/4] Only use payload if it actually matches declared event type Closes gh-22426 --- .../ApplicationListenerMethodAdapter.java | 18 ++--- .../event/PayloadApplicationEventTests.java | 72 +++++++++++++++++++ 2 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index 6cbe6e0cd3..e81ff3633c 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -188,9 +188,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe /** * Resolve the method arguments to use for the specified {@link ApplicationEvent}. - *

These arguments will be used to invoke the method handled by this instance. Can - * return {@code null} to indicate that no suitable arguments could be resolved and - * therefore the method should not be invoked at all for the specified event. + *

These arguments will be used to invoke the method handled by this instance. + * Can return {@code null} to indicate that no suitable arguments could be resolved + * and therefore the method should not be invoked at all for the specified event. */ @Nullable protected Object[] resolveArguments(ApplicationEvent event) { @@ -201,13 +201,15 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe if (this.method.getParameterCount() == 0) { return new Object[0]; } - if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.toClass()) && + Class declaredEventClass = declaredEventType.toClass(); + if (!ApplicationEvent.class.isAssignableFrom(declaredEventClass) && event instanceof PayloadApplicationEvent) { - return new Object[] {((PayloadApplicationEvent) event).getPayload()}; - } - else { - return new Object[] {event}; + Object payload = ((PayloadApplicationEvent) event).getPayload(); + if (declaredEventClass.isInstance(payload)) { + return new Object[] {payload}; + } } + return new Object[] {event}; } protected void handleResult(Object result) { diff --git a/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java b/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java new file mode 100644 index 0000000000..c9f9c17996 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/event/PayloadApplicationEventTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2019 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.event; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.PayloadApplicationEvent; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.stereotype.Component; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class PayloadApplicationEventTests { + + @Test + public void testEventClassWithInterface() { + ApplicationContext ac = new AnnotationConfigApplicationContext(Listener.class); + MyEventClass event = new MyEventClass<>(this, "xyz"); + ac.publishEvent(event); + assertTrue(ac.getBean(Listener.class).events.contains(event)); + } + + + public interface Auditable { + } + + + public static class MyEventClass extends PayloadApplicationEvent implements Auditable { + + public MyEventClass(Object source, GT payload) { + super(source, payload); + } + + public String toString() { + return "Payload: " + getPayload(); + } + } + + + @Component + public static class Listener { + + public final List events = new ArrayList<>(); + + @EventListener + public void onEvent(Auditable event) { + events.add(event); + } + } + +} From f07014ad37258e5d7eadbd64d28820e7fac61204 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 25 Feb 2019 17:21:08 +0100 Subject: [PATCH 2/4] MappingJackson2MessageConverter delegates default encoding to Jackson Closes gh-22444 --- .../MappingJackson2MessageConverter.java | 35 +++++++++++++------ .../MappingJackson2MessageConverterTests.java | 15 ++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java index 9971bfc361..01b1ce9e43 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -74,7 +74,8 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B private MessageType targetType = MessageType.BYTES; - private String encoding = DEFAULT_ENCODING; + @Nullable + private String encoding; @Nullable private String encodingPropertyName; @@ -293,13 +294,21 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B throws JMSException, IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); - OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding); - objectWriter.writeValue(writer, object); + if (this.encoding != null) { + OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding); + objectWriter.writeValue(writer, object); + } + else { + // Jackson usually defaults to UTF-8 but can also go straight to bytes, e.g. for Smile. + // We use a direct byte array argument for the latter case to work as well. + objectWriter.writeValue(bos, object); + } BytesMessage message = session.createBytesMessage(); message.writeBytes(bos.toByteArray()); if (this.encodingPropertyName != null) { - message.setStringProperty(this.encodingPropertyName, this.encoding); + message.setStringProperty(this.encodingPropertyName, + (this.encoding != null ? this.encoding : DEFAULT_ENCODING)); } return message; } @@ -393,12 +402,18 @@ public class MappingJackson2MessageConverter implements SmartMessageConverter, B } byte[] bytes = new byte[(int) message.getBodyLength()]; message.readBytes(bytes); - try { - String body = new String(bytes, encoding); - return this.objectMapper.readValue(body, targetJavaType); + if (encoding != null) { + try { + String body = new String(bytes, encoding); + return this.objectMapper.readValue(body, targetJavaType); + } + catch (UnsupportedEncodingException ex) { + throw new MessageConversionException("Cannot convert bytes to String", ex); + } } - catch (UnsupportedEncodingException ex) { - throw new MessageConversionException("Cannot convert bytes to String", ex); + else { + // Jackson internally performs encoding detection, falling back to UTF-8. + return this.objectMapper.readValue(bytes, targetJavaType); } } diff --git a/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java b/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java index e98fefdedd..9866935f90 100644 --- a/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/support/converter/MappingJackson2MessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -56,7 +56,7 @@ public class MappingJackson2MessageConverterTests { @Before - public void setUp() throws Exception { + public void setup() { sessionMock = mock(Session.class); converter = new MappingJackson2MessageConverter(); converter.setEncodingPropertyName("__encoding__"); @@ -263,8 +263,11 @@ public class MappingJackson2MessageConverterTests { return new MyAnotherBean(); } + public static class MyBean { + private String foo; + public MyBean() { } @@ -272,8 +275,6 @@ public class MappingJackson2MessageConverterTests { this.foo = foo; } - private String foo; - public String getFoo() { return foo; } @@ -290,13 +291,10 @@ public class MappingJackson2MessageConverterTests { if (o == null || getClass() != o.getClass()) { return false; } - MyBean bean = (MyBean) o; - if (foo != null ? !foo.equals(bean.foo) : bean.foo != null) { return false; } - return true; } @@ -306,9 +304,12 @@ public class MappingJackson2MessageConverterTests { } } + private interface Summary {}; + private interface Full extends Summary {}; + private static class MyAnotherBean { @JsonView(Summary.class) From cb54f201c2ae92fdeb4af93caef670911b787ba0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 25 Feb 2019 17:24:02 +0100 Subject: [PATCH 3/4] Break out of loop once an AspectJ advice has been found Closes gh-22449 --- .../aop/aspectj/AspectJProxyUtils.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java index 329722b5d6..ce06f9cde0 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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,27 +27,31 @@ import org.springframework.aop.interceptor.ExposeInvocationInterceptor; * * @author Rod Johnson * @author Ramnivas Laddad + * @author Juergen Hoeller * @since 2.0 */ public abstract class AspectJProxyUtils { /** - * Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors. - * This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut matching) - * and make available the current AspectJ JoinPoint. The call will have no effect if there are no - * AspectJ advisors in the advisor chain. + * Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors: + * concretely, {@link ExposeInvocationInterceptor} at the beginning of the list. + *

This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut + * matching) and make available the current AspectJ JoinPoint. The call will have no effect + * if there are no AspectJ advisors in the advisor chain. * @param advisors the advisors available - * @return {@code true} if any special {@link Advisor Advisors} were added, otherwise {@code false} + * @return {@code true} if an {@link ExposeInvocationInterceptor} was added to the list, + * otherwise {@code false} */ public static boolean makeAdvisorChainAspectJCapableIfNecessary(List advisors) { // Don't add advisors to an empty list; may indicate that proxying is just not required if (!advisors.isEmpty()) { boolean foundAspectJAdvice = false; for (Advisor advisor : advisors) { - // Be careful not to get the Advice without a guard, as - // this might eagerly instantiate a non-singleton AspectJ aspect + // Be careful not to get the Advice without a guard, as this might eagerly + // instantiate a non-singleton AspectJ aspect... if (isAspectJAdvice(advisor)) { foundAspectJAdvice = true; + break; } } if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) { From 9eb7f7e2947e895389e4fb7e96a8762f43860020 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 25 Feb 2019 17:36:37 +0100 Subject: [PATCH 4/4] Polishing --- ...athScanningCandidateComponentProvider.java | 4 ++-- .../annotation/ConfigurationClassParser.java | 6 ++--- .../ConfigurationClassPostProcessor.java | 4 ++-- .../AbstractApplicationEventMulticaster.java | 4 ++-- .../support/AbstractApplicationContext.java | 2 +- .../support/ResourceBundleMessageSource.java | 4 ++-- .../context/support/SimpleThreadScope.java | 15 ++++++------- .../org/springframework/util/ClassUtils.java | 4 ++-- .../messaging/simp/stomp/StompSession.java | 8 +++---- .../org/springframework/http/HttpHeaders.java | 4 ++-- .../server/adapter/HttpWebHandlerAdapter.java | 19 +++++++--------- .../web/servlet/DispatcherServlet.java | 10 ++++----- .../AnnotationDrivenBeanDefinitionParser.java | 8 +++---- .../web/servlet/config/MvcNamespaceUtils.java | 14 ++++++------ .../handler/AbstractUrlHandlerMapping.java | 4 ++-- .../HandlerExceptionResolverComposite.java | 9 ++++---- .../condition/PatternsRequestCondition.java | 4 ++-- ...nfoHandlerMethodMappingNamingStrategy.java | 4 ++-- .../ExceptionHandlerExceptionResolver.java | 4 ++-- ...essionAttributeMethodArgumentResolver.java | 6 ++--- .../ViewMethodReturnValueHandler.java | 4 ++-- .../ViewNameMethodReturnValueHandler.java | 22 +++++++++---------- 22 files changed, 78 insertions(+), 85 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java index 0d7e4ddd05..3ea331e9c4 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -377,7 +377,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC for (TypeFilter filter : this.includeFilters) { String stereotype = extractStereotype(filter); if (stereotype == null) { - throw new IllegalArgumentException("Failed to extract stereotype from "+ filter); + throw new IllegalArgumentException("Failed to extract stereotype from " + filter); } types.addAll(index.getCandidateTypes(basePackage, stereotype)); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 2b2c6be0f8..9d48811f33 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -946,7 +946,7 @@ class ConfigurationClassParser { return new AssignableTypeFilter(clazz).match((MetadataReader) this.source, metadataReaderFactory); } - public ConfigurationClass asConfigClass(ConfigurationClass importedBy) throws IOException { + public ConfigurationClass asConfigClass(ConfigurationClass importedBy) { if (this.source instanceof Class) { return new ConfigurationClass((Class) this.source, importedBy); } @@ -1014,7 +1014,7 @@ class ConfigurationClassParser { return result; } - public Set getAnnotations() throws IOException { + public Set getAnnotations() { Set result = new LinkedHashSet<>(); for (String className : this.metadata.getAnnotationTypes()) { try { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index a5f9cbfd64..20284b8a93 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -435,7 +435,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo } @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) { + public Object postProcessBeforeInitialization(Object bean, String beanName) { if (bean instanceof ImportAware) { ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName()); diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index 5cd9385027..a1811030af 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -269,7 +269,7 @@ public abstract class AbstractApplicationEventMulticaster * type before trying to instantiate it. *

If this method returns {@code true} for a given listener as a first pass, * the listener instance will get retrieved and fully evaluated through a - * {@link #supportsEvent(ApplicationListener,ResolvableType, Class)} call afterwards. + * {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards. * @param listenerType the listener's type as determined by the BeanFactory * @param eventType the event type to check * @return whether the given listener should be included in the candidates diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 54c3850158..25831f3a6b 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1251,7 +1251,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @Override @Nullable public A findAnnotationOnBean(String beanName, Class annotationType) - throws NoSuchBeanDefinitionException{ + throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().findAnnotationOnBean(beanName, annotationType); diff --git a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java index da7563a3fa..d516d93695 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -377,7 +377,7 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou try { return bundle.getString(key); } - catch (MissingResourceException ex){ + catch (MissingResourceException ex) { // Assume key not found for some other reason // -> do NOT throw the exception to allow for checking parent message source. } diff --git a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java index 6571423673..eb1d364f22 100644 --- a/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java +++ b/spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -36,14 +36,13 @@ import org.springframework.lang.Nullable; * or through a {@link org.springframework.beans.factory.config.CustomScopeConfigurer} bean. * *

{@code SimpleThreadScope} does not clean up any objects associated with it. - * As such, it is typically preferable to use - * {@link org.springframework.web.context.request.RequestScope RequestScope} - * in web environments. + * It is therefore typically preferable to use a request-bound scope implementation such + * as {@code org.springframework.web.context.request.RequestScope} in web environments, + * implementing the full lifecycle for scoped attributes (including reliable destruction). * - *

For an implementation of a thread-based {@code Scope} with support for - * destruction callbacks, refer to the - * -* Spring by Example Custom Thread Scope Module. + *

For an implementation of a thread-based {@code Scope} with support for destruction + * callbacks, refer to + * Spring by Example. * *

Thanks to Eugene Kuleshov for submitting the original prototype for a thread scope! * diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index 6fe5907907..75af805eea 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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,7 +42,7 @@ import java.util.Set; import org.springframework.lang.Nullable; /** - * Miscellaneous class utility methods. + * Miscellaneous {@code java.lang.Class} utility methods. * Mainly for internal use within the framework. * * @author Juergen Hoeller diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java index 7a6c6a0851..f0906515e6 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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,8 +19,8 @@ package org.springframework.messaging.simp.stomp; import org.springframework.lang.Nullable; /** - * Represents a STOMP session with operations to send messages, create - * subscriptions and receive messages on those subscriptions. + * Represents a STOMP session with operations to send messages, + * create subscriptions and receive messages on those subscriptions. * * @author Rossen Stoyanchev * @since 4.2 @@ -63,7 +63,7 @@ public interface StompSession { * {@link StompHeaders} instead of just a destination. The headers must * contain a destination and may also have other headers such as * "content-type" or custom headers for the broker to propagate to - * subscribers, or broker-specific, non-standard headers.. + * subscribers, or broker-specific, non-standard headers. * @param headers the message headers * @param payload the message payload * @return a Receiptable for tracking receipts 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 bb46958e29..23fa9a697a 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -1681,7 +1681,7 @@ public class HttpHeaders implements MultiValueMap, Serializable /** - * Return a {@code HttpHeaders} object that can only be read, not written to. + * Return an {@code HttpHeaders} object that can only be read, not written to. */ public static HttpHeaders readOnlyHttpHeaders(HttpHeaders headers) { Assert.notNull(headers, "HttpHeaders must not be null"); @@ -1694,7 +1694,7 @@ public class HttpHeaders implements MultiValueMap, Serializable } /** - * Return a {@code HttpHeaders} object that can be read and written to. + * Return an {@code HttpHeaders} object that can be read and written to. * @since 5.1.1 */ public static HttpHeaders writableHttpHeaders(HttpHeaders headers) { diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java b/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java index 7968d1b874..594b4ef989 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -197,8 +197,7 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa /** * Configure the {@code ApplicationContext} associated with the web application, * if it was initialized with one via - * {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder#applicationContext - * WebHttpHandlerBuilder#applicationContext}. + * {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder#applicationContext(ApplicationContext)}. * @param applicationContext the context * @since 5.0.3 */ @@ -232,11 +231,9 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa @Override public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { - if (this.forwardedHeaderTransformer != null) { request = this.forwardedHeaderTransformer.apply(request); } - ServerWebExchange exchange = createExchange(request, response); LogFormatUtils.traceDebug(logger, traceOn -> @@ -274,7 +271,6 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa } private Mono handleUnresolvedError(ServerWebExchange exchange, Throwable ex) { - ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); String logPrefix = exchange.getLogPrefix(); @@ -294,18 +290,19 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa return Mono.empty(); } else { - // After the response is committed, propagate errors to the server.. + // After the response is committed, propagate errors to the server... logger.error(logPrefix + "Error [" + ex + "] for " + formatRequest(request) + ", but ServerHttpResponse already committed (" + response.getStatusCode() + ")"); return Mono.error(ex); } } - private boolean isDisconnectedClientError(Throwable ex) { + private boolean isDisconnectedClientError(Throwable ex) { String message = NestedExceptionUtils.getMostSpecificCause(ex).getMessage(); - message = (message != null ? message.toLowerCase() : ""); - String className = ex.getClass().getSimpleName(); - return (message.contains("broken pipe") || DISCONNECTED_CLIENT_EXCEPTIONS.contains(className)); + if (message != null && message.toLowerCase().contains("broken pipe")) { + return true; + } + return DISCONNECTED_CLIENT_EXCEPTIONS.contains(ex.getClass().getSimpleName()); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index d1a1bda6af..fe7b82f23a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -960,7 +960,7 @@ public class DispatcherServlet extends FrameworkServlet { .collect(Collectors.joining(", ")); } else { - params = (request.getParameterMap().isEmpty() ? "" : "masked"); + params = (request.getParameterMap().isEmpty() ? "" : "masked"); } String query = StringUtils.isEmpty(request.getQueryString()) ? "" : "?" + request.getQueryString(); @@ -1166,7 +1166,7 @@ public class DispatcherServlet extends FrameworkServlet { logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter"); } } - else if (hasMultipartException(request) ) { + else if (hasMultipartException(request)) { logger.debug("Multipart resolution previously failed for current request - " + "skipping re-resolution for undisturbed error rendering"); } @@ -1432,7 +1432,7 @@ public class DispatcherServlet extends FrameworkServlet { * @param attributesSnapshot the snapshot of the request attributes before the include */ @SuppressWarnings("unchecked") - private void restoreAttributesAfterInclude(HttpServletRequest request, Map attributesSnapshot) { + private void restoreAttributesAfterInclude(HttpServletRequest request, Map attributesSnapshot) { // Need to copy into separate Collection here, to avoid side effects // on the Enumeration when removing attributes. Set attrsToCheck = new HashSet<>(); @@ -1451,7 +1451,7 @@ public class DispatcherServlet extends FrameworkServlet { // or removing the attribute, respectively, if appropriate. for (String attrName : attrsToCheck) { Object attrValue = attributesSnapshot.get(attrName); - if (attrValue == null){ + if (attrValue == null) { request.removeAttribute(attrName); } else if (attrValue != request.getAttribute(attrName)) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 1980325b82..f8eb3dc3b6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -213,7 +213,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { } configurePathMatchingProperties(handlerMappingDef, element, context); - readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef); + readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef); RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source); handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef); @@ -265,7 +265,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors); handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors); - readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef); + readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); RootBeanDefinition uriContributorDef = new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class); @@ -391,7 +391,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes()); String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME; - context.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef); + context.getReaderContext().getRegistry().registerBeanDefinition(name, factoryBeanDef); context.registerComponent(new BeanComponentDefinition(factoryBeanDef, name)); beanRef = new RuntimeBeanReference(name); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java index e19610eead..fea91536f0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -82,8 +82,8 @@ public abstract class MvcNamespaceUtils { } parserContext.getRegistry().registerAlias(urlPathHelperRef.getBeanName(), URL_PATH_HELPER_BEAN_NAME); } - else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME) - && !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) { + else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME) && + !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) { RootBeanDefinition urlPathHelperDef = new RootBeanDefinition(UrlPathHelper.class); urlPathHelperDef.setSource(source); urlPathHelperDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -107,8 +107,8 @@ public abstract class MvcNamespaceUtils { } parserContext.getRegistry().registerAlias(pathMatcherRef.getBeanName(), PATH_MATCHER_BEAN_NAME); } - else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME) - && !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { + else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME) && + !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { RootBeanDefinition pathMatcherDef = new RootBeanDefinition(AntPathMatcher.class); pathMatcherDef.setSource(source); pathMatcherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -123,7 +123,7 @@ public abstract class MvcNamespaceUtils { * name unless already registered. */ private static void registerBeanNameUrlHandlerMapping(ParserContext context, @Nullable Object source) { - if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)){ + if (!context.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)) { RootBeanDefinition mappingDef = new RootBeanDefinition(BeanNameUrlHandlerMapping.class); mappingDef.setSource(source); mappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); @@ -195,7 +195,7 @@ public abstract class MvcNamespaceUtils { * unless already registered. */ private static void registerHandlerMappingIntrospector(ParserContext parserContext, @Nullable Object source) { - if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)){ + if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) { RootBeanDefinition beanDef = new RootBeanDefinition(HandlerMappingIntrospector.class); beanDef.setSource(source); beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 23113fe245..1c875326ea 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -179,7 +179,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i } else if (useTrailingSlashMatch()) { if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) { - matchingPatterns.add(registeredPattern +"/"); + matchingPatterns.add(registeredPattern + "/"); } } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java index 43d7afc37a..b08bd6f295 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerExceptionResolverComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -67,13 +67,12 @@ public class HandlerExceptionResolverComposite implements HandlerExceptionResolv /** * Resolve the exception by iterating over the list of configured exception resolvers. - *

The first one to return a {@link ModelAndView} wins. Otherwise {@code null} - * is returned. + *

The first one to return a {@link ModelAndView} wins. Otherwise {@code null} is returned. */ @Override @Nullable - public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, - @Nullable Object handler,Exception ex) { + public ModelAndView resolveException( + HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) { if (this.resolvers != null) { for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java index 3dac4f2d17..7a435fc3ee 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -256,7 +256,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition argumentResolvers) { - this.customArgumentResolvers= argumentResolvers; + this.customArgumentResolvers = argumentResolvers; } /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java index 471c96ca60..04d6baf8fd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SessionAttributeMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -50,14 +50,14 @@ public class SessionAttributeMethodArgumentResolver extends AbstractNamedValueMe @Override @Nullable - protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request){ + protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) { return request.getAttribute(name, RequestAttributes.SCOPE_SESSION); } @Override protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException { throw new ServletRequestBindingException("Missing session attribute '" + name + - "' of type " + parameter.getNestedParameterType().getSimpleName()); + "' of type " + parameter.getNestedParameterType().getSimpleName()); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java index eee3b9a4e2..e5752a4111 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -50,7 +50,7 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { - if (returnValue instanceof View){ + if (returnValue instanceof View) { View view = (View) returnValue; mavContainer.setView(view); if (view instanceof SmartView && ((SmartView) view).isRedirectView()) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java index 207e3b747a..d0f7780c5d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ViewNameMethodReturnValueHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -33,10 +33,10 @@ import org.springframework.web.servlet.RequestToViewNameTranslator; * as the actual return value is left as-is allowing the configured * {@link RequestToViewNameTranslator} to select a view name by convention. * - *

A String return value can be interpreted in more than one ways depending - * on the presence of annotations like {@code @ModelAttribute} or - * {@code @ResponseBody}. Therefore this handler should be configured after - * the handlers that support these annotations. + *

A String return value can be interpreted in more than one ways depending on + * the presence of annotations like {@code @ModelAttribute} or {@code @ResponseBody}. + * Therefore this handler should be configured after the handlers that support these + * annotations. * * @author Rossen Stoyanchev * @author Juergen Hoeller @@ -49,12 +49,10 @@ public class ViewNameMethodReturnValueHandler implements HandlerMethodReturnValu /** - * Configure one more simple patterns (as described in - * {@link PatternMatchUtils#simpleMatch}) to use in order to recognize - * custom redirect prefixes in addition to "redirect:". - *

Note that simply configuring this property will not make a custom - * redirect prefix work. There must be a custom View that recognizes the - * prefix as well. + * Configure one more simple patterns (as described in {@link PatternMatchUtils#simpleMatch}) + * to use in order to recognize custom redirect prefixes in addition to "redirect:". + *

Note that simply configuring this property will not make a custom redirect prefix work. + * There must be a custom View that recognizes the prefix as well. * @since 4.1 */ public void setRedirectPatterns(@Nullable String... redirectPatterns) { @@ -87,7 +85,7 @@ public class ViewNameMethodReturnValueHandler implements HandlerMethodReturnValu mavContainer.setRedirectModelScenario(true); } } - else if (returnValue != null){ + else if (returnValue != null) { // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod());