在spring2.0中使用自定義屬性編輯器

當以一個字符串值來設置bean屬性時,Spring IoC 容器最終使用標準的JavaBean PropertyEditor來將這些字符串轉化成複雜的數據類型。Spring預先註冊了一些PropertyEditor(舉例來說,將一個以字符串表示的Class轉化成Class對象)。除此之外,Java標準的JavaBean PropertyEditor會識別在同一包結構下的類和它對應的命名恰當的Editor,並自動將其作爲這個類的的Editor。
比如
Address類有一個PhoneNumber屬性
package com.springinaction.propertyeditor;

public class Address {
 private PhoneNumber phoneNumber;

 public PhoneNumber getPhoneNumber() {
  return phoneNumber;
 }

 public void setPhoneNumber(PhoneNumber phoneNumber) {
  this.phoneNumber = phoneNumber;
 }

}
PhoneNumber類:
package com.springinaction.propertyeditor;

public class PhoneNumber {
 private String areaCode;
 private String prefix;
 private String number;

 public PhoneNumber(String areaCode, String prefix, String number) {
  this.areaCode = areaCode;
  this.prefix = prefix;
  this.number = number;
 }

 //省略getter和setter,toString()方法

}
PhoneNumberEditor類:
package com.springinaction.propertyeditor;

import java.beans.PropertyEditorSupport;

public class PhoneNumberEditor extends PropertyEditorSupport {

 @Override
 public void setAsText(String text) throws IllegalArgumentException {
  // TODO Auto-generated method stub
//  super.setAsText(text);
  String stripped = strippedNonNumber(text);
  String areaCode = stripped.substring(0,3);
  String prefix = stripped.substring(3,6);
  String number = stripped.substring(6);
  PhoneNumber phone = new PhoneNumber(areaCode,prefix,number);
  setValue(phone);
 }
 public String strippedNonNumber(String original){
  StringBuffer allNumbers = new StringBuffer();
  for(int i=0;i<original.length();i++){
   char c = original.charAt(i);
   if(Character.isDigit(c)){
    allNumbers.append(c);
   }
  }
  return allNumbers.toString();
 }
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
 

</beans>
測試代碼:
package com.springinaction.propertyeditor;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class PropertyEditorTest {
 public static void main(String[] args) {
  BeanFactory bf = new XmlBeanFactory(new ClassPathResource(
    "com/springinaction/propertyeditor/editor.xml"));
 
  Address address = (Address) bf.getBean("address");
  System.out.println(address.getPhoneNumber());
 }
}
因爲PhoneNumber類和PhoneNumberEditor類在同一個包下,不用註冊PhoneNumberEditor,就能將字符串類型的800-900-6789轉換成PhoneNumber類型。
如果PhoneNumber類相應的編輯器類名不是PhoneNumberEditor,而是別的名字,比如PhoneEditor,上面其它的代碼和配置都不變,再運行測試類的時候就會報
java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.springinaction.propertyeditor.PhoneNumber]異常。
要解決這個問題,需要註冊自定義的編輯器和將XmlBeanFactory改成ApplicationContext。
可以通過customEditors屬性註冊編輯器或者通過propertyEditorRegistrars屬性註冊編輯器。
customEditors屬性方式註冊:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

 <bean id="customEditorConfigurer"
  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
   <map>
    <entry key="com.springinaction.propertyeditor.PhoneNumber">
     <bean id="phoneEditor" class="com.springinaction.propertyeditor.PhoneEditor">
     </bean>
    </entry>
   </map>
  </property>
 </bean>
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
</beans>
propertyEditorRegistrars屬性方式註冊:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

 <bean id="editorRegister" class="com.springinaction.propertyeditor.PhoneEditorRegister" />
 <bean id="customEditorConfigurer"
  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="propertyEditorRegistrars">
   <ref bean="editorRegister" />
  </property>
 </bean>
 <bean id="address" class="com.springinaction.propertyeditor.Address">
  <property name="phoneNumber">
   <value>800-900-6789</value>
  </property>
 </bean>
</beans>
添加的PhoneEditorRegister類代碼如下,它實現了PropertyEditorRegistrar,註冊了PhoneEditor。
package com.springinaction.propertyeditor;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;

public class PhoneEditorRegister implements PropertyEditorRegistrar {

 public void registerCustomEditors(PropertyEditorRegistry registry) {
  
  registry.registerCustomEditor(com.springinaction.propertyeditor.PhoneNumber.class,
    new PhoneEditor());
 }

}
測試類修改如下:
package com.springinaction.propertyeditor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class PropertyEditorTest {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext(
    "com/springinaction/propertyeditor/editor.xml");
  Address address = (Address) context.getBean("address");
    System.out.println(address.getPhoneNumber());
 }
}
這時在運行測試類,字符串類型的值800-900-6789就可以成功轉換成PhoneNumber類型了,控制檯會輸出800-900-6789。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章