From b0ed385f84f8610f5fe482d319c881f3aaa771ac Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 31 Mar 2018 17:06:33 +0200 Subject: [PATCH] Polishing --- .../aop/aspectj/AbstractAspectJAdvice.java | 12 +++++------ .../groovy/GroovyBeanDefinitionReader.java | 13 +++--------- .../org/springframework/beans/BeanUtils.java | 14 ++++++------- .../beans/MutablePropertyValues.java | 10 +++------- .../annotation/ConfigurationClassParser.java | 9 +++++---- .../ListenableFutureCallbackRegistry.java | 12 ++++++----- .../expression/spel/ast/ValueRef.java | 8 ++++---- .../support/ReflectivePropertyAccessor.java | 5 +---- .../AbstractListenerContainerParser.java | 15 ++++++-------- .../test/web/servlet/MockMvc.java | 20 ++++++------------- .../web/filter/ShallowEtagHeaderFilter.java | 16 ++++++--------- .../web/util/UrlPathHelper.java | 5 +---- src/asciidoc/core-validation.adoc | 10 +++++----- src/asciidoc/web-mvc.adoc | 6 +++--- 14 files changed, 62 insertions(+), 93 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java index a5ed7d1131..898602433d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -227,7 +227,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence } /** - * Sets the declaration order of this advice within the aspect + * Set the declaration order of this advice within the aspect. */ public void setDeclarationOrder(int order) { this.declarationOrder = order; @@ -366,7 +366,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence * to which argument name. There are multiple strategies for determining * this binding, which are arranged in a ChainOfResponsibility. */ - public synchronized final void calculateArgumentBindings() { + public final synchronized void calculateArgumentBindings() { // The simple case... nothing to bind. if (this.argumentsIntrospected || this.parameterTypes.length == 0) { return; @@ -374,10 +374,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence int numUnboundArgs = this.parameterTypes.length; Class[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes(); - if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) { - numUnboundArgs--; - } - else if (maybeBindJoinPointStaticPart(parameterTypes[0])) { + if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0]) || + maybeBindJoinPointStaticPart(parameterTypes[0])) { numUnboundArgs--; } diff --git a/spring-beans-groovy/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java b/spring-beans-groovy/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java index 723f31cddc..dbc949dd72 100644 --- a/spring-beans-groovy/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java +++ b/spring-beans-groovy/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionReader.java @@ -381,10 +381,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp refName = args[0].toString(); } boolean parentRef = false; - if (args.length > 1) { - if (args[1] instanceof Boolean) { - parentRef = (Boolean) args[1]; - } + if (args.length > 1 && args[1] instanceof Boolean) { + parentRef = (Boolean) args[1]; } return new RuntimeBeanReference(refName, parentRef); } @@ -411,12 +409,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp } private boolean addDeferredProperty(String property, Object newValue) { - if (newValue instanceof List) { - this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property, - new DeferredProperty(this.currentBeanDefinition, property, newValue)); - return true; - } - else if (newValue instanceof Map) { + if (newValue instanceof List || newValue instanceof Map) { this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property, new DeferredProperty(this.currentBeanDefinition, property, newValue)); return true; diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index ca0ea7ab45..0cdf050a2a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -311,23 +311,23 @@ public abstract class BeanUtils { public static Method resolveSignature(String signature, Class clazz) { Assert.hasText(signature, "'signature' must not be empty"); Assert.notNull(clazz, "Class must not be null"); - int firstParen = signature.indexOf('('); - int lastParen = signature.indexOf(')'); - if (firstParen > -1 && lastParen == -1) { + int startParen = signature.indexOf('('); + int endParen = signature.indexOf(')'); + if (startParen > -1 && endParen == -1) { throw new IllegalArgumentException("Invalid method signature '" + signature + "': expected closing ')' for args list"); } - else if (lastParen > -1 && firstParen == -1) { + else if (startParen == -1 && endParen > -1) { throw new IllegalArgumentException("Invalid method signature '" + signature + "': expected opening '(' for args list"); } - else if (firstParen == -1 && lastParen == -1) { + else if (startParen == -1 && endParen == -1) { return findMethodWithMinimalParameters(clazz, signature); } else { - String methodName = signature.substring(0, firstParen); + String methodName = signature.substring(0, startParen); String[] parameterTypeNames = - StringUtils.commaDelimitedListToStringArray(signature.substring(firstParen + 1, lastParen)); + StringUtils.commaDelimitedListToStringArray(signature.substring(startParen + 1, endParen)); Class[] parameterTypes = new Class[parameterTypeNames.length]; for (int i = 0; i < parameterTypeNames.length; i++) { String parameterTypeName = parameterTypeNames[i].trim(); diff --git a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java index efb4ae9bbd..8167613a0f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2018 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. @@ -262,7 +262,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable { /** * Get the raw property value, if any. * @param propertyName the name to search for - * @return the raw property value, or {@code null} + * @return the raw property value, or {@code null} if none found * @since 4.0 * @see #getPropertyValue(String) * @see PropertyValue#getValue() @@ -283,11 +283,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable { for (PropertyValue newPv : this.propertyValueList) { // if there wasn't an old one, add it PropertyValue pvOld = old.getPropertyValue(newPv.getName()); - if (pvOld == null) { - changes.addPropertyValue(newPv); - } - else if (!pvOld.equals(newPv)) { - // it's changed + if (pvOld == null || !pvOld.equals(newPv)) { changes.addPropertyValue(newPv); } } 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 b6af650b19..cde17d81c5 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 @@ -561,7 +561,7 @@ class ConfigurationClassParser { } private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, - Collection importCandidates, boolean checkForCircularImports) throws IOException { + Collection importCandidates, boolean checkForCircularImports) { if (importCandidates.isEmpty()) { return; @@ -702,7 +702,8 @@ class ConfigurationClassParser { @SuppressWarnings("serial") private static class ImportStack extends ArrayDeque implements ImportRegistry { - private final MultiValueMap imports = new LinkedMultiValueMap(); + private final MultiValueMap imports = + new LinkedMultiValueMap(); public void registerImport(AnnotationMetadata importingClass, String importedClass) { this.imports.add(importedClass, importingClass); @@ -948,9 +949,9 @@ class ConfigurationClassParser { public CircularImportProblem(ConfigurationClass attemptedImport, Deque importStack) { super(String.format("A circular @Import has been detected: " + "Illegal attempt by @Configuration class '%s' to import class '%s' as '%s' is " + - "already present in the current import stack %s", importStack.peek().getSimpleName(), + "already present in the current import stack %s", importStack.element().getSimpleName(), attemptedImport.getSimpleName(), attemptedImport.getSimpleName(), importStack), - new Location(importStack.peek().getResource(), attemptedImport.getMetadata())); + new Location(importStack.element().getResource(), attemptedImport.getMetadata())); } } diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java index 46eb746bbc..eca80014c6 100644 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java +++ b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -134,8 +134,9 @@ public class ListenableFutureCallbackRegistry { synchronized (this.mutex) { this.state = State.SUCCESS; this.result = result; - while (!this.successCallbacks.isEmpty()) { - notifySuccess(this.successCallbacks.poll()); + SuccessCallback callback; + while ((callback = this.successCallbacks.poll()) != null) { + notifySuccess(callback); } } } @@ -149,8 +150,9 @@ public class ListenableFutureCallbackRegistry { synchronized (this.mutex) { this.state = State.FAILURE; this.result = ex; - while (!this.failureCallbacks.isEmpty()) { - notifyFailure(this.failureCallbacks.poll()); + FailureCallback callback; + while ((callback = this.failureCallbacks.poll()) != null) { + notifyFailure(callback); } } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java index 8ba7f0ad1a..8e9b8a87b5 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2018 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. @@ -57,7 +57,7 @@ public interface ValueRef { /** * A ValueRef for the null value. */ - static class NullValueRef implements ValueRef { + class NullValueRef implements ValueRef { static final NullValueRef INSTANCE = new NullValueRef(); @@ -84,13 +84,13 @@ public interface ValueRef { /** * A ValueRef holder for a single value, which cannot be set. */ - static class TypedValueHolderValueRef implements ValueRef { + class TypedValueHolderValueRef implements ValueRef { private final TypedValue typedValue; private final SpelNodeImpl node; // used only for error reporting - public TypedValueHolderValueRef(TypedValue typedValue,SpelNodeImpl node) { + public TypedValueHolderValueRef(TypedValue typedValue, SpelNodeImpl node) { this.typedValue = typedValue; this.node = node; } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 0766dbbe47..d6a8f6e218 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -349,10 +349,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { if (typeDescriptor == null) { // Attempt to populate the cache entry try { - if (canRead(context, target, name)) { - typeDescriptor = this.typeDescriptorCache.get(cacheKey); - } - else if (canWrite(context, target, name)) { + if (canRead(context, target, name) || canWrite(context, target, name)) { typeDescriptor = this.typeDescriptorCache.get(cacheKey); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java index 2bc28bc073..01d6bc253c 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractListenerContainerParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -263,16 +263,13 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser { boolean replyPubSubDomain = false; String replyDestinationType = containerEle.getAttribute(RESPONSE_DESTINATION_TYPE_ATTRIBUTE); - if (DESTINATION_TYPE_TOPIC.equals(replyDestinationType)) { + if (!StringUtils.hasText(replyDestinationType)) { + replyPubSubDomain = pubSubDomain; // the default: same value as pubSubDomain + } + else if (DESTINATION_TYPE_TOPIC.equals(replyDestinationType)) { replyPubSubDomain = true; } - else if (DESTINATION_TYPE_QUEUE.equals(replyDestinationType)) { - replyPubSubDomain = false; - } - else if (!StringUtils.hasText(replyDestinationType)) { - replyPubSubDomain = pubSubDomain; // the default: same value as pubSubDomain - } - else if (StringUtils.hasText(replyDestinationType)) { + else if (!DESTINATION_TYPE_QUEUE.equals(replyDestinationType)) { parserContext.getReaderContext().error("Invalid listener container 'response-destination-type': only " + "\"queue\", \"topic\" supported.", containerEle); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java index 1734dad294..c0ee0485f2 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvc.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,6 +90,7 @@ public final class MockMvc { this.servletContext = servletContext; } + /** * A default request builder merged into every performed request. * @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#defaultRequest(RequestBuilder) @@ -103,7 +104,7 @@ public final class MockMvc { * @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#alwaysExpect(ResultMatcher) */ void setGlobalResultMatchers(List resultMatchers) { - Assert.notNull(resultMatchers, "resultMatchers is required"); + Assert.notNull(resultMatchers, "ResultMatcher List is required"); this.defaultResultMatchers = resultMatchers; } @@ -112,20 +113,17 @@ public final class MockMvc { * @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#alwaysDo(ResultHandler) */ void setGlobalResultHandlers(List resultHandlers) { - Assert.notNull(resultHandlers, "resultHandlers is required"); + Assert.notNull(resultHandlers, "ResultHandler List is required"); this.defaultResultHandlers = resultHandlers; } /** * Perform a request and return a type that allows chaining further * actions, such as asserting expectations, on the result. - * * @param requestBuilder used to prepare the request to execute; * see static factory methods in * {@link org.springframework.test.web.servlet.request.MockMvcRequestBuilders} - * - * @return an instance of {@link ResultActions}; never {@code null} - * + * @return an instance of {@link ResultActions} (never {@code null}) * @see org.springframework.test.web.servlet.request.MockMvcRequestBuilders * @see org.springframework.test.web.servlet.result.MockMvcResultMatchers */ @@ -153,29 +151,24 @@ public final class MockMvc { filterChain.doFilter(request, response); if (DispatcherType.ASYNC.equals(request.getDispatcherType()) && - request.getAsyncContext() != null & !request.isAsyncStarted()) { - + request.getAsyncContext() != null && !request.isAsyncStarted()) { request.getAsyncContext().complete(); } applyDefaultResultActions(mvcResult); - RequestContextHolder.setRequestAttributes(previousAttributes); return new ResultActions() { - @Override public ResultActions andExpect(ResultMatcher matcher) throws Exception { matcher.match(mvcResult); return this; } - @Override public ResultActions andDo(ResultHandler handler) throws Exception { handler.handle(mvcResult); return this; } - @Override public MvcResult andReturn() { return mvcResult; @@ -184,7 +177,6 @@ public final class MockMvc { } private void applyDefaultResultActions(MvcResult mvcResult) throws Exception { - for (ResultMatcher matcher : this.defaultResultMatchers) { matcher.match(mvcResult); } diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index 9aea5252a3..88de97452b 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -128,10 +128,8 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { String responseETag = generateETagHeaderValue(responseWrapper.getContentInputStream(), this.writeWeakETag); rawResponse.setHeader(HEADER_ETAG, responseETag); String requestETag = request.getHeader(HEADER_IF_NONE_MATCH); - if (requestETag != null - && (responseETag.equals(requestETag) - || responseETag.replaceFirst("^W/", "").equals(requestETag.replaceFirst("^W/", "")) - || "*".equals(requestETag))) { + if (requestETag != null && ("*".equals(requestETag) || responseETag.equals(requestETag) || + responseETag.replaceFirst("^W/", "").equals(requestETag.replaceFirst("^W/", "")))) { if (logger.isTraceEnabled()) { logger.trace("ETag [" + responseETag + "] equal to If-None-Match, sending 304"); } @@ -165,15 +163,13 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { * @param response the HTTP response * @param responseStatusCode the HTTP response status code * @param inputStream the response body - * @return {@code true} if eligible for ETag generation; {@code false} otherwise + * @return {@code true} if eligible for ETag generation, {@code false} otherwise */ protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response, int responseStatusCode, InputStream inputStream) { String method = request.getMethod(); - if (responseStatusCode >= 200 && responseStatusCode < 300 - && HttpMethod.GET.matches(method)) { - + if (responseStatusCode >= 200 && responseStatusCode < 300 && HttpMethod.GET.matches(method)) { String cacheControl = null; if (servlet3Present) { cacheControl = response.getHeader(HEADER_CACHE_CONTROL); @@ -194,7 +190,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { * @see org.springframework.util.DigestUtils */ protected String generateETagHeaderValue(InputStream inputStream, boolean isWeak) throws IOException { - // length of W/ + 0 + " + 32bits md5 hash + " + // length of W/ + " + 0 + 32bits md5 hash + " StringBuilder builder = new StringBuilder(37); if (isWeak) { builder.append("W/"); diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index e5d87d5153..5acd5ed672 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -259,10 +259,7 @@ public class UrlPathHelper { } c1 = requestUri.charAt(index1); } - if (c1 == c2) { - continue; - } - else if (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2))) { + if (c1 == c2 || (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2)))) { continue; } return null; diff --git a/src/asciidoc/core-validation.adoc b/src/asciidoc/core-validation.adoc index 64604b6dab..d3555a7e0b 100644 --- a/src/asciidoc/core-validation.adoc +++ b/src/asciidoc/core-validation.adoc @@ -1095,7 +1095,7 @@ The `number` package provides a `NumberFormatter`, `CurrencyFormatter`, and `PercentFormatter` to format `java.lang.Number` objects using a `java.text.NumberFormat`. The `datetime` package provides a `DateFormatter` to format `java.util.Date` objects with a `java.text.DateFormat`. The `datetime.joda` package provides comprehensive datetime -formatting support based on the http://joda-time.sourceforge.net[Joda Time library]. +formatting support based on the http://joda-time.sourceforge.net[Joda-Time library]. Consider `DateFormatter` as an example `Formatter` implementation: @@ -1227,7 +1227,7 @@ To trigger formatting, simply annotate fields with @NumberFormat: ==== Format Annotation API A portable format annotation API exists in the `org.springframework.format.annotation` package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to -format java.util.Date, java.util.Calendar, java.util.Long, or Joda Time fields. +format java.util.Date, java.util.Calendar, java.util.Long, or Joda-Time fields. The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date (yyyy-MM-dd): @@ -1328,10 +1328,10 @@ You will need to ensure that Spring does not register default formatters, and in you should register all formatters manually. Use the `org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar` or `org.springframework.format.datetime.DateFormatterRegistrar` class depending on whether -you use the Joda Time library. +you use the Joda-Time library. For example, the following Java configuration will register a global ' `yyyyMMdd`' -format. This example does not depend on the Joda Time library: +format. This example does not depend on the Joda-Time library: [source,java,indent=0] [subs="verbatim,quotes"] @@ -1396,7 +1396,7 @@ Time: [NOTE] ==== -Joda Time provides separate distinct types to represent `date`, `time` and `date-time` +Joda-Time provides separate distinct types to represent `date`, `time` and `date-time` values. The `dateFormatter`, `timeFormatter` and `dateTimeFormatter` properties of the `JodaTimeFormatterRegistrar` should be used to configure the different formats for each type. The `DateTimeFormatterFactoryBean` provides a convenient way to create formatters. diff --git a/src/asciidoc/web-mvc.adoc b/src/asciidoc/web-mvc.adoc index 6a7096ef51..ae051ad653 100644 --- a/src/asciidoc/web-mvc.adoc +++ b/src/asciidoc/web-mvc.adoc @@ -4841,7 +4841,7 @@ It also enables the following: in addition to the JavaBeans PropertyEditors used for Data Binding. . Support for <> Number fields using the `@NumberFormat` annotation through the `ConversionService`. -. Support for <> `Date`, `Calendar`, `Long`, and Joda Time fields using the +. Support for <> `Date`, `Calendar`, `Long`, and Joda-Time fields using the `@DateTimeFormat` annotation. . Support for <> `@Controller` inputs with `@Valid`, if a JSR-303 Provider is present on the classpath. @@ -4925,8 +4925,8 @@ available. === Conversion and Formatting By default formatters for `Number` and `Date` types are installed, including support for -the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda Time -formatting library is also installed if Joda Time is present on the classpath. To +the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time +formatting library is also installed if Joda-Time is present on the classpath. To register custom formatters and converters, override the `addFormatters` method: [source,java,indent=0]