2013-02-21 28 views
0

我在Spring和Pro Spring中搜索了文檔。我不明白CustomerEditorConfigurer如何知道它應該應用屬性轉換。防爆 -Spring PropertyEditor如何知道要轉換的類屬性

我有一個聯繫類具有日期變量(jodatTime) 我創建whcih延伸PropertyEditorSupport,我使用setAsText()轉換成字符串日期ContactPropertyEditor。

然後我進入應用程序並定義CustomerEditorConfigurer,我告訴它將jodaTime映射到ContactPropertyEditor。現在沒有這些信息告訴Spring,當一個Contact類被創建時,使用ContactPropertyEditor進行轉換。

因此,爲了測試我的理論,我創建了與Contact相同的屬性(Date)的另一個類Contact2。當我運行Contact2時也發生了這種轉換,這有點奇怪。

下面是代碼樣品 Contact.java

public class Contact { 
private String firstName; 
private String lastName; 
private DateTime birthDate; 
private URL personalSite; 



public String toString() { 
return "First name: " + getFirstName() 
+ " - Last name: " + getLastName() 
+ " - Birth date: " + getBirthDate() 
+ " - Personal site: " + getPersonalSite(); 
} 
// Getter/setter methods omitted 
public String getFirstName() { 
    return firstName; 
} 

public void setFirstName(String firstName) { 
    this.firstName = firstName; 
} 

public String getLastName() { 
    return lastName; 
} 

public void setLastName(String lastName) { 
    this.lastName = lastName; 
} 

public DateTime getBirthDate() { 
    return birthDate; 
} 

public void setBirthDate(DateTime birthDate) { 
    this.birthDate = birthDate; 
} 

public URL getPersonalSite() { 
    return personalSite; 
} 

public void setPersonalSite(URL personalSite) { 
    this.personalSite = personalSite; 
} 
} 

ContactPropertyEditor.java 進口java.beans.PropertyEditorSupport中;

import org.joda.time.DateTime; 
import org.joda.time.format.DateTimeFormat; 
import org.joda.time.format.DateTimeFormatter; 
import org.springframework.stereotype.Component; 


public class ContactPropertEditor extends PropertyEditorSupport{ 

private DateTimeFormatter dateTimeFormatter; 

public ContactPropertEditor(String formatPattern){ 
    System.out.println("In the constructor"); 
    dateTimeFormatter=DateTimeFormat.forPattern(formatPattern); 
} 

public void setAsText(String text) throws IllegalArgumentException{ 
    System.out.println("Setting the value of " + text); 
    setValue(DateTime.parse(text, dateTimeFormatter)); 
} 

} 

的applicationContext.xml現在

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:util="http://www.springframework.org/schema/util"  xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

<context:component-scan base-package="com.dinesh"></context:component-scan> 
<context:annotation-config /> 

<!-- This holds the property values and formats --> 
<context:property-placeholder location="classpath:application.properties" /> 

<bean class="com.dinesh.PropertyEditor.ContactPropertEditor" id="contactPropertEditor"> 
    <constructor-arg><value>"yyyy-MM-dd"</value></constructor-arg> 
</bean> 
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 
    <property name="customEditors"> 
     <map> 
      <entry key="org.joda.time.DateTime"> 
       <ref local="contactPropertEditor" /> 
      </entry> 
     </map> 
    </property> 
</bean> 

<bean id="clarence" class="com.dinesh.PropertyEditor.Contact" 
    p:firstName="Clarence" p:lastName="Ho" p:birthDate="1970-12-31" 
    p:personalSite="http://www.clarence.com" /> 



<bean id="contact2" class="com.dinesh.PropertyEditor.Customer2" 
    p:firstName="Clarence" p:lastName="Ho" p:birthDate="1970-12-31" 
    p:personalSite="http://www.clarence.com" /> 

,你可以看到所有我做的是告訴org.springframework.beans.factory.config.CustomEditorConfigurer我proprty轉換邏輯contactPropertEditor類。我不告訴Spring將它應用於Contact.java類。

魔法是怎麼發生的。

在Spring文檔中,它說明了其他有意義的東西。

Spring文檔有一個名爲ExoticType()的類,它具有name屬性。 稱爲ExoticTypeEditor一個編輯CALSS用來名稱chaage爲大寫和應用程序上下文XML是明確

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 
<property name="customEditors"> 
    <map> 
    <entry key="example.ExoticType" value="example.ExoticTypeEditor"/> 
    </map> 
</property> 

在這裏我可以看到我告訴,使用ExoticTypeEditor階級的ExoticType應用轉化CustomEditorConfigurer的,但在Pro Spring 3書中並不是這樣。我試圖在聯繫示例中做同樣的事情,但遇到了錯誤。

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 
    <property name="customEditors"> 
     <map> 
      <entry key="com.dinesh.PropertyEditor.Contact"> 
       <ref local="contactPropertEditor" /> 
      </entry> 
     </map> 
    </property> 
</bean> 

錯誤:無法將類型的值[java.lang.String中]至所需的類型[org.joda.time.DateTime]爲屬性「生日」:沒有匹配的編輯器或轉換策略發現

任何想法我錯過了什麼?

回答

1

當您在註冊應用程序上下文PropertyEditor,你是從String提供轉換到某種類型的,你的情況JodaTime類型。持有該類型的bean(Contact)無關緊要。在需要將JodaTime類型的屬性設置爲String任意 bean上時,應用程序上下文將使用您的ContactPropertyEditor編輯器。

所以ContactPropertyEdit這是一個壞名字。它應該是JodaTimePropertyEditor。

如果你想要一個真實的ContactPropertyEditor,它應該將字符串轉換爲聯繫人。例如:

<bean id="someBeanHoldingAContact" class="someBeanClass"> 
<property name="contact" value="Hendrix, Jimi, 1942-11-27, http://www.jimihendrix.com" /> 
</bean> 

和ContactPropertyEditor應該使用字符串值來創建聯繫人。

魔法org.springframework.beans.BeanWrapperImp類。請參閱javadoc

+0

- 謝謝。我現在明白了。所以這就像一個全球編輯。任何使用JodaTime的bean都會受到影響。沒有辦法選擇性地做。假設我只想對特定的Bean應用propertyEditor。 – 2013-02-26 17:10:15

+0

不,容器在查找屬性編輯器時不檢查目標類。但是您可以在bean本身中實現轉換,或者注入由容器中部署的其他bean方法返回的對象。 – 2013-02-26 17:25:50

0

如果用戶搜索此標題以嘗試查找如何在轉換時動態獲取目標類,則可以嘗試使用ConditionalGenericConverter。

相關部分:

檢查每一個轉換請求:

@Override 
public Set<ConvertiblePair> getConvertibleTypes() { 
    return null;//accept everything 
} 

檢查時,如果你處理這種情況或將其傳遞到彈簧默認轉換器請求轉換:

@Override 
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { 
     if (sourceType.getType().equals(String.class) && MyInterface.class.isAssignableFrom(targetType.getType())) 
     return true; 
return false; 
} 

處理轉換:

@Override 
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {  
output = targetType.getType().newInstance(); 
//do whatever is required here 
return output; 
} 
相關問題