Avoid NPE in ObjectToObjectConverter

Bypass ObjectToObject conversion when source and object types are
identical and protect against a null source object.

Prior to this commit the TypeDescriptor was used to determine if
conversion was necessary.  This caused issues when comparing a
descriptor with annotations to one without.  The updated code
now compares using TypeDescriptor.getType().

The ObjectToObject converter will now no longer attempt to convert
null source objects.

Issue: SPR-9933
master
Phillip Webb 12 years ago
parent 9055a7f810
commit 31331e6ad3
  1. 9
      spring-core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.java
  2. 18
      spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java

@ -48,10 +48,17 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return !sourceType.equals(targetType) && hasValueOfMethodOrConstructor(targetType.getType(), sourceType.getType());
if (sourceType.getType().equals(targetType.getType())) {
// no conversion required
return false;
}
return hasValueOfMethodOrConstructor(targetType.getType(), sourceType.getType());
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return null;
}
Class<?> sourceClass = sourceType.getType();
Class<?> targetClass = targetType.getType();
Method method = getValueOfMethodOn(targetClass, sourceClass);

@ -18,6 +18,8 @@ package org.springframework.core.convert.support;
import java.awt.Color;
import java.awt.SystemColor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -744,6 +746,22 @@ public class GenericConversionServiceTests {
assertEquals("1", result);
}
@Test
public void convertNullAnnotatedStringToString() throws Exception {
DefaultConversionService.addDefaultConverters(conversionService);
String source = null;
TypeDescriptor sourceType = new TypeDescriptor(getClass().getField("annotatedString"));
TypeDescriptor targetType = TypeDescriptor.valueOf(String.class);
conversionService.convert(source, sourceType, targetType);
}
@ExampleAnnotation
public String annotatedString;
@Retention(RetentionPolicy.RUNTIME)
public static @interface ExampleAnnotation {
}
private static class MyConditionalConverter implements Converter<String, Color>,
ConditionalConverter {

Loading…
Cancel
Save