【问题标题】:How does Spring PropertyEditor know which Class propert to convertSpring PropertyEditor 如何知道要转换哪个 Class 属性
【发布时间】:2013-02-21 17:53:09
【问题描述】:

我在 Spring 和 Pro Spring 中搜索了文档。我不明白 CustomerEditorConfigurer 如何知道它应该在哪里应用属性转换。前 -

我有一个联系人类,它有一个日期变量(jodatTime) 我创建了一个扩展 PropertyEditorSupport 的 ContactPropertyEditor,我正在使用 setAsText() 来转换字符串日期。

然后我进入应用程序并定义 CustomerEditorConfigurer,我告诉它将 jodaTime 映射到 ContactPropertyEditor。现在这没有信息告诉 Spring 在创建 Contact 类时使用 ContactPropertyEditor 进行转换。

所以为了测试我的理论,我创建了另一个类 Contact2,其属性(日期)与 Contact 相同。当我运行转换时,Contact2 也会发生,这有点奇怪。

这是代码示例 联系方式.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 我的属性转换逻辑是 contactPropertEditor 类。我没有告诉 Spring 在 Contact.java 类上应用这个。

魔法是如何发生的。

在 Spring 文档中,它说了一些有意义的东西。

Spring 文档有一个名为 ExoticType() 的类,它具有 name 属性。 一个名为 ExoticTypeEditor 的编辑器用于将名称更改为大写,并且应用程序上下文 xml 清晰

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

在这里我可以看到我告诉 CustomEditorConfigurer 使用 ExoticTypeEditor 对类 ExoticType 应用转换,但在 Pro Spring 3 书中并非如此。我尝试在 Contact Example 中执行相同操作,但出现错误。

<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] 的值转换为属性“birthDate”所需的类型 [org.joda.time.DateTime]:找不到匹配的编辑器或转换策略

知道我错过了什么吗?

【问题讨论】:

    标签: spring propertyeditor


    【解决方案1】:

    当您在应用程序上下文中注册PropertyEditor 时,您将提供从String 到某种类型的转换器,在您的情况下为JodaTime 类型。持有类型的 bean (Contact) 无关紧要。只要需要在 any bean 上将 JodaTime 类型的属性设置为 String,应用程序上下文就会使用您的 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

    【讨论】:

    • -谢谢。我现在明白了。所以这就像一个全局编辑器。任何使用 JodaTime 的 bean 都会受到影响。没有办法选择性地做到这一点。假设我只想在特定的 Bean 上应用 propertyEditor。
    • 不,容器在查找属性编辑器时不检查目标类。但是您可以在 bean 本身中实现转换,或者注入容器中部署的其他 bean 方法返回的对象。
    【解决方案2】:

    如果人们搜索这个标题试图找到如何在转换时动态获取目标类,您可以尝试使用 ConditionalGenericConverter。

    相关部分:

    检查每个转换请求:

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

    如果您处理这种情况或将其传递给spring默认转换器,请检查何时请求转换:

     @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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多