From 21ac764e5c751c21fe7508f1ba49bc9621f6891c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 24 Mar 2017 13:41:34 +0100 Subject: [PATCH] Polishing --- ...onfigurationClassBeanDefinitionReader.java | 6 +- .../core/metadata/CallParameterMetaData.java | 22 +++-- .../core/metadata/TableParameterMetaData.java | 3 +- .../orm/jpa/EntityManagerFactoryUtils.java | 8 +- .../testng/TrackingTestNGTestListener.java | 8 +- .../SimpleClientHttpRequestFactory.java | 24 ++--- .../web/bind/WebDataBinder.java | 12 +-- .../web/client/ResponseErrorHandler.java | 17 ++-- .../web/util/HtmlCharacterEntityDecoder.java | 87 +++++++++---------- .../json/GsonHttpMessageConverterTests.java | 15 ++-- .../ExtendedServletRequestDataBinder.java | 9 +- .../ServletModelAttributeMethodProcessor.java | 24 ++--- 12 files changed, 130 insertions(+), 105 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 6db58bbc81..b4abf0f4d8 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -186,7 +186,7 @@ class ConfigurationClassBeanDefinitionReader { // Consider name and any aliases AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); List names = new ArrayList(Arrays.asList(bean.getStringArray("name"))); - String beanName = (names.size() > 0 ? names.remove(0) : methodName); + String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden for (String alias : names) { @@ -336,7 +336,7 @@ class ConfigurationClassBeanDefinitionReader { } readerInstanceCache.put(readerClass, reader); } - catch (Exception ex) { + catch (Throwable ex) { throw new IllegalStateException( "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]"); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java index 55e747b9cd..a10b05cfd1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2017 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. @@ -21,16 +21,23 @@ package org.springframework.jdbc.core.metadata; * * @author Thomas Risberg * @since 2.5 + * @see GenericCallMetaDataProvider */ public class CallParameterMetaData { + private String parameterName; + private int parameterType; + private int sqlType; + private String typeName; + private boolean nullable; + /** - * Constructor taking all the properties + * Constructor taking all the properties. */ public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) { this.parameterName = columnName; @@ -45,34 +52,35 @@ public class CallParameterMetaData { * Get the parameter name. */ public String getParameterName() { - return parameterName; + return this.parameterName; } /** * Get the parameter type. */ public int getParameterType() { - return parameterType; + return this.parameterType; } /** * Get the parameter SQL type. */ public int getSqlType() { - return sqlType; + return this.sqlType; } /** * Get the parameter type name. */ public String getTypeName() { - return typeName; + return this.typeName; } /** * Get whether the parameter is nullable. */ public boolean isNullable() { - return nullable; + return this.nullable; } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableParameterMetaData.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableParameterMetaData.java index 4488063b70..f63f29f470 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableParameterMetaData.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableParameterMetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2017 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. @@ -21,6 +21,7 @@ package org.springframework.jdbc.core.metadata; * * @author Thomas Risberg * @since 2.5 + * @see GenericTableMetaDataProvider */ public class TableParameterMetaData { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java index 219beb3cc9..31f7ade1db 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java @@ -450,7 +450,8 @@ public abstract class EntityManagerFactoryUtils { /** * Callback for resource cleanup at the end of a non-JPA transaction - * (e.g. when participating in a JtaTransactionManager transaction). + * (e.g. when participating in a JtaTransactionManager transaction), + * fully synchronized with the ongoing transaction. * @see org.springframework.transaction.jta.JtaTransactionManager */ private static class TransactionalEntityManagerSynchronization @@ -465,6 +466,7 @@ public abstract class EntityManagerFactoryUtils { public TransactionalEntityManagerSynchronization( EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) { + super(emHolder, emf); this.transactionData = txData; this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ? @@ -512,7 +514,9 @@ public abstract class EntityManagerFactoryUtils { } @Override - protected void cleanupResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) { + protected void cleanupResource( + EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) { + if (!committed) { // Clear all pending inserts/updates/deletes in the EntityManager. // Necessary for pre-bound EntityManagers, to avoid inconsistent state. diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/TrackingTestNGTestListener.java b/spring-test/src/test/java/org/springframework/test/context/testng/TrackingTestNGTestListener.java index a47edcb552..c7030a112c 100644 --- a/spring-test/src/test/java/org/springframework/test/context/testng/TrackingTestNGTestListener.java +++ b/spring-test/src/test/java/org/springframework/test/context/testng/TrackingTestNGTestListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -30,8 +30,11 @@ import org.testng.ITestResult; public class TrackingTestNGTestListener implements ITestListener { public int testStartCount = 0; + public int testSuccessCount = 0; + public int testFailureCount = 0; + public int failedConfigurationsCount = 0; @@ -66,4 +69,5 @@ public class TrackingTestNGTestListener implements ITestListener { public void onTestSuccess(ITestResult testResult) { this.testSuccessCount++; } -} \ No newline at end of file + +} diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index 3aff0c9221..aa369188fb 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -64,13 +64,15 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, } /** - * Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body} - * internally. - *

Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended - * to change this property to {@code false}, so as not to run out of memory. This will result in a - * {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection} - * (if the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} is known in advance), - * or that will use "Chunked transfer encoding" (if the {@code Content-Length} is not known in advance). + * Indicate whether this request factory should buffer the + * {@linkplain ClientHttpRequest#getBody() request body} internally. + *

Default is {@code true}. When sending large amounts of data via POST or PUT, + * it is recommended to change this property to {@code false}, so as not to run + * out of memory. This will result in a {@link ClientHttpRequest} that either + * streams directly to the underlying {@link HttpURLConnection} (if the + * {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} + * is known in advance), or that will use "Chunked transfer encoding" + * (if the {@code Content-Length} is not known in advance). * @see #setChunkSize(int) * @see HttpURLConnection#setFixedLengthStreamingMode(int) */ @@ -79,9 +81,11 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, } /** - * Sets the number of bytes to write in each chunk when not buffering request bodies locally. - *

Note that this parameter is only used when {@link #setBufferRequestBody(boolean) bufferRequestBody} is set - * to {@code false}, and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} + * Set the number of bytes to write in each chunk when not buffering request + * bodies locally. + *

Note that this parameter is only used when + * {@link #setBufferRequestBody(boolean) bufferRequestBody} is set to {@code false}, + * and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} * is not known in advance. * @see #setBufferRequestBody(boolean) */ diff --git a/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java index 442b97185b..48756e854a 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -248,11 +248,11 @@ public class WebDataBinder extends DataBinder { * Determine an empty value for the specified field. *

Default implementation returns: *

    - *
  • {@code Boolean.FALSE} for boolean fields - *
  • an empty array for array types - *
  • Collection implementations for Collection types - *
  • Map implementations for Map types - *
  • else, {@code null} is used as default + *
  • {@code Boolean.FALSE} for boolean fields + *
  • an empty array for array types + *
  • Collection implementations for Collection types + *
  • Map implementations for Map types + *
  • else, {@code null} is used as default *
* @param field the name of the field * @param fieldType the type of the field diff --git a/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java index 39ddfe4dd1..2ad6db4589 100644 --- a/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -21,7 +21,8 @@ import java.io.IOException; import org.springframework.http.client.ClientHttpResponse; /** - * Strategy interface used by the {@link RestTemplate} to determine whether a particular response has an error or not. + * Strategy interface used by the {@link RestTemplate} to determine + * whether a particular response has an error or not. * * @author Arjen Poutsma * @since 3.0 @@ -29,9 +30,9 @@ import org.springframework.http.client.ClientHttpResponse; public interface ResponseErrorHandler { /** - * Indicates whether the given response has any errors. - * Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus} - * of the response. + * Indicate whether the given response has any errors. + *

Implementations will typically inspect the + * {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response. * @param response the response to inspect * @return {@code true} if the response has an error; {@code false} otherwise * @throws IOException in case of I/O errors @@ -39,10 +40,12 @@ public interface ResponseErrorHandler { boolean hasError(ClientHttpResponse response) throws IOException; /** - * Handles the error in the given response. - * This method is only called when {@link #hasError(ClientHttpResponse)} has returned {@code true}. + * Handle the error in the given response. + *

This method is only called when {@link #hasError(ClientHttpResponse)} + * has returned {@code true}. * @param response the response with the error * @throws IOException in case of I/O errors */ void handleError(ClientHttpResponse response) throws IOException; + } diff --git a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java index 75fac9a1d6..3fffd7f07b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java +++ b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2017 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. @@ -45,90 +45,88 @@ class HtmlCharacterEntityDecoder { public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) { this.characterEntityReferences = characterEntityReferences; this.originalMessage = original; - this.decodedMessage = new StringBuilder(originalMessage.length()); + this.decodedMessage = new StringBuilder(original.length()); } + public String decode() { - while (currentPosition < originalMessage.length()) { - findNextPotentialReference(currentPosition); + while (this.currentPosition < this.originalMessage.length()) { + findNextPotentialReference(this.currentPosition); copyCharactersTillPotentialReference(); processPossibleReference(); } - return decodedMessage.toString(); + return this.decodedMessage.toString(); } private void findNextPotentialReference(int startPosition) { - nextPotentialReferencePosition = Math.max(startPosition, nextSemicolonPosition - MAX_REFERENCE_SIZE); + this.nextPotentialReferencePosition = Math.max(startPosition, this.nextSemicolonPosition - MAX_REFERENCE_SIZE); do { - nextPotentialReferencePosition = - originalMessage.indexOf('&', nextPotentialReferencePosition); + this.nextPotentialReferencePosition = + this.originalMessage.indexOf('&', this.nextPotentialReferencePosition); - if (nextSemicolonPosition != -1 && - nextSemicolonPosition < nextPotentialReferencePosition) - nextSemicolonPosition = originalMessage.indexOf(';', nextPotentialReferencePosition + 1); + if (this.nextSemicolonPosition != -1 && + this.nextSemicolonPosition < this.nextPotentialReferencePosition) + this.nextSemicolonPosition = this.originalMessage.indexOf(';', this.nextPotentialReferencePosition + 1); - boolean isPotentialReference = - nextPotentialReferencePosition != -1 - && nextSemicolonPosition != -1 - && nextPotentialReferencePosition - nextSemicolonPosition < MAX_REFERENCE_SIZE; + boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 && + this.nextSemicolonPosition != -1 && + this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE); if (isPotentialReference) { break; } - if (nextPotentialReferencePosition == -1) { + if (this.nextPotentialReferencePosition == -1) { break; } - if (nextSemicolonPosition == -1) { - nextPotentialReferencePosition = -1; + if (this.nextSemicolonPosition == -1) { + this.nextPotentialReferencePosition = -1; break; } - nextPotentialReferencePosition = nextPotentialReferencePosition + 1; + this.nextPotentialReferencePosition = this.nextPotentialReferencePosition + 1; } - while (nextPotentialReferencePosition != -1); + while (this.nextPotentialReferencePosition != -1); } - private void copyCharactersTillPotentialReference() { - if (nextPotentialReferencePosition != currentPosition) { - int skipUntilIndex = nextPotentialReferencePosition != -1 ? - nextPotentialReferencePosition : originalMessage.length(); - if (skipUntilIndex - currentPosition > 3) { - decodedMessage.append(originalMessage.substring(currentPosition, skipUntilIndex)); - currentPosition = skipUntilIndex; + if (this.nextPotentialReferencePosition != this.currentPosition) { + int skipUntilIndex = (this.nextPotentialReferencePosition != -1 ? + this.nextPotentialReferencePosition : this.originalMessage.length()); + if (skipUntilIndex - this.currentPosition > 3) { + this.decodedMessage.append(this.originalMessage.substring(this.currentPosition, skipUntilIndex)); + this.currentPosition = skipUntilIndex; } else { - while (currentPosition < skipUntilIndex) - decodedMessage.append(originalMessage.charAt(currentPosition++)); + while (this.currentPosition < skipUntilIndex) + this.decodedMessage.append(this.originalMessage.charAt(this.currentPosition++)); } } } private void processPossibleReference() { - if (nextPotentialReferencePosition != -1) { - boolean isNumberedReference = originalMessage.charAt(currentPosition + 1) == '#'; + if (this.nextPotentialReferencePosition != -1) { + boolean isNumberedReference = (this.originalMessage.charAt(this.currentPosition + 1) == '#'); boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference(); if (wasProcessable) { - currentPosition = nextSemicolonPosition + 1; + this.currentPosition = this.nextSemicolonPosition + 1; } else { - char currentChar = originalMessage.charAt(currentPosition); - decodedMessage.append(currentChar); - currentPosition++; + char currentChar = this.originalMessage.charAt(this.currentPosition); + this.decodedMessage.append(currentChar); + this.currentPosition++; } } } private boolean processNumberedReference() { - boolean isHexNumberedReference = - originalMessage.charAt(nextPotentialReferencePosition + 2) == 'x' || - originalMessage.charAt(nextPotentialReferencePosition + 2) == 'X'; + char referenceChar = this.originalMessage.charAt(this.nextPotentialReferencePosition + 2); + boolean isHexNumberedReference = (referenceChar == 'x' || referenceChar == 'X'); try { - int value = (!isHexNumberedReference) ? + int value = (!isHexNumberedReference ? Integer.parseInt(getReferenceSubstring(2)) : - Integer.parseInt(getReferenceSubstring(3), 16); - decodedMessage.append((char) value); + Integer.parseInt(getReferenceSubstring(3), 16)); + this.decodedMessage.append((char) value); return true; } catch (NumberFormatException ex) { @@ -138,16 +136,17 @@ class HtmlCharacterEntityDecoder { private boolean processNamedReference() { String referenceName = getReferenceSubstring(1); - char mappedCharacter = characterEntityReferences.convertToCharacter(referenceName); + char mappedCharacter = this.characterEntityReferences.convertToCharacter(referenceName); if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) { - decodedMessage.append(mappedCharacter); + this.decodedMessage.append(mappedCharacter); return true; } return false; } private String getReferenceSubstring(int referenceOffset) { - return originalMessage.substring(nextPotentialReferencePosition + referenceOffset, nextSemicolonPosition); + return this.originalMessage.substring( + this.nextPotentialReferencePosition + referenceOffset, this.nextSemicolonPosition); } } diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/GsonHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/GsonHttpMessageConverterTests.java index c71f750b33..5365b943a1 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/GsonHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/GsonHttpMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -94,7 +94,7 @@ public class GsonHttpMessageConverterTests { assertEquals(42, n.longValue()); n = (Number) result.get("fraction"); assertEquals(42D, n.doubleValue(), 0D); - List array = new ArrayList(); + List array = new ArrayList<>(); array.add("Foo"); array.add("Bar"); assertEquals(array, result.get("array")); @@ -118,15 +118,14 @@ public class GsonHttpMessageConverterTests { body.setBool(true); body.setBytes(new byte[]{0x1, 0x2}); this.converter.write(body, null, outputMessage); - Charset utf8 = Charset.forName("UTF-8"); - String result = outputMessage.getBodyAsString(utf8); + String result = outputMessage.getBodyAsString(UTF8); assertTrue(result.contains("\"string\":\"Foo\"")); assertTrue(result.contains("\"number\":42")); assertTrue(result.contains("fraction\":42.0")); assertTrue(result.contains("\"array\":[\"Foo\",\"Bar\"]")); assertTrue(result.contains("\"bool\":true")); assertTrue(result.contains("\"bytes\":[1,2]")); - assertEquals("Invalid content-type", new MediaType("application", "json", utf8), + assertEquals("Invalid content-type", new MediaType("application", "json", UTF8), outputMessage.getHeaders().getContentType()); } @@ -166,8 +165,7 @@ public class GsonHttpMessageConverterTests { }; String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," + "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]"; - MockHttpInputMessage inputMessage = new MockHttpInputMessage( - body.getBytes(UTF8)); + MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(UTF8)); inputMessage.getHeaders().setContentType(new MediaType("application", "json")); List results = (List) converter.read(List.class, inputMessage); @@ -189,8 +187,7 @@ public class GsonHttpMessageConverterTests { String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," + "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]"; - MockHttpInputMessage inputMessage = new MockHttpInputMessage( - body.getBytes(UTF8)); + MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(UTF8)); inputMessage.getHeaders().setContentType(new MediaType("application", "json")); GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java index ce1a1642a4..e559e99317 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -54,6 +54,7 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder { super(target, objectName); } + /** * Merge URI variables into the property values to use for data binding. */ @@ -65,8 +66,10 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder { if (uriVars != null) { for (Entry entry : uriVars.entrySet()) { if (mpvs.contains(entry.getKey())) { - logger.warn("Skipping URI variable '" + entry.getKey() - + "' since the request contains a bind value with the same name."); + if (logger.isWarnEnabled()) { + logger.warn("Skipping URI variable '" + entry.getKey() + + "' since the request contains a bind value with the same name."); + } } else { mpvs.addPropertyValue(entry.getKey(), entry.getValue()); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java index 6fcea9d548..293b27d6b6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -48,6 +48,7 @@ import org.springframework.web.servlet.HandlerMapping; public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor { /** + * Class constructor. * @param annotationNotRequired if "true", non-simple method arguments and * return values are considered model attributes with or without a * {@code @ModelAttribute} annotation @@ -87,19 +88,19 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr * a URI variable first and then a request parameter. * @param attributeName the model attribute name * @param request the current request - * @return the request value to try to convert or {@code null} + * @return the request value to try to convert, or {@code null} if none */ protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) { Map variables = getUriTemplateVariables(request); - if (StringUtils.hasText(variables.get(attributeName))) { - return variables.get(attributeName); + String variableValue = variables.get(attributeName); + if (StringUtils.hasText(variableValue)) { + return variableValue; } - else if (StringUtils.hasText(request.getParameter(attributeName))) { - return request.getParameter(attributeName); - } - else { - return null; + String parameterValue = request.getParameter(attributeName); + if (StringUtils.hasText(parameterValue)) { + return parameterValue; } + return null; } @SuppressWarnings("unchecked") @@ -115,11 +116,12 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr *

The default implementation converts only if there a registered * {@link Converter} that can perform the conversion. * @param sourceValue the source value to create the model attribute from - * @param attributeName the name of the attribute, never {@code null} + * @param attributeName the name of the attribute (never {@code null}) * @param methodParam the method parameter * @param binderFactory for creating WebDataBinder instance * @param request the current request - * @return the created model attribute, or {@code null} + * @return the created model attribute, or {@code null} if no suitable + * conversion found * @throws Exception */ protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,