java.beans.PropertyEditor
嚴格上來講,其實並不能算spring框架的接口,很明顯看包名就明白此類是JDK自帶的。是Sun所制定的一套JavaBean規範,是爲IDE圖形化界面準備設置屬性值的接口。看接口源碼上的說明:java
A PropertyEditor class provides support for GUIs that want to allow users to edit a property value of a giventype.
這接口本來是使用在GUI圖形程序中,容許用戶給giventype設定屬性值的。(不熟悉圖形化界面API,不知道giventype是什麼,怎麼翻譯)web
public interface PropertyEditor { void setValue(Object value); Object getValue(); boolean isPaintable(); void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box); String getJavaInitializationString(); String getAsText(); void setAsText(String text) throws java.lang.IllegalArgumentException; String[] getTags(); java.awt.Component getCustomEditor(); boolean supportsCustomEditor(); void addPropertyChangeListener(PropertyChangeListener listener); void removePropertyChangeListener(PropertyChangeListener listener); }
不要被這麼多的方法給嚇到,對於咱們使用者來講其實重點只有下面4個方法:spring
void setValue(Object value);
設置屬性值 Object getValue();
獲取屬性值String getAsText();
把屬性值轉換成stringvoid setAsText(String text);
把string轉換成屬性值因此Java很機智地提供了一個適配器java.beans.PropertyEditorSupport
來幫助咱們實現屬性值的轉換,它幫助咱們實現了GUI部分的接口,咱們只須要重寫getAsText
和setAsText
的邏輯。mvc
那麼這個接口跟spring有什麼鳥關係呢,這個接口有什麼用呢?請看示例1。app
一個由區號和號碼組成的座機號碼實體類:框架
package com.demo.domain; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @NoArgsConstructor @AllArgsConstructor public class Telephone { /* 區號 */ private String areaCode; /* 號碼 */ private String phone; @Override public String toString() { return areaCode + "-" + phone; } }
一我的的實體(屏蔽了無關屬性,只有座機-_-):dom
package com.demo.domain; import org.springframework.beans.factory.annotation.Value; import lombok.Getter; import lombok.Setter; @Getter @Setter public class PersonEntity { @Value("010-12345") private Telephone telephone; }
@Value
是spring的註解,至關於xml配置<property name="" value=""/>
裏面的value,給屬性賦值的。可是請注意,這裏賦的是字符串。ide
那麼問題來了,這個010-12345的字符串是怎麼賦到Telephone這個類對象上的呢?類型根本轉不過來。spring-boot
答案就是實現轉換器PropertyEditor
。post
package com.demo.mvc.component; import java.beans.PropertyEditorSupport; import com.demo.domain.Telephone; public class TelephonePropertyEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { if (text.matches("^\\d+\\-\\d+$")) { String[] strs = text.split("\\-"); setValue(new Telephone(strs[0], strs[1])); } else { throw new IllegalArgumentException(); } } @Override public String getAsText() { return ((Telephone) getValue()).toString(); } }
實現完了接口還得註冊到spring容器讓spring管理:
<bean class="com.demo.domain.PersonEntity" /> <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="com.demo.domain.Telephone" value="com.demo.mvc.component.TelephonePropertyEditor" /> </map> </property> </bean>
這個CustomEditorConfigurer
類顧名思義就是配置自定義的屬性轉換器的。把自定義的轉換器通通放進這個名叫customEditors的Map結構裏。用key指定Telephone,value指定TelephonePropertyEditor。
就是告訴spring,當遇到Telephone這個類型時,使用TelephonePropertyEditor把字符串轉化成Telephone。
單元測試:
package com.junit; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.demo.domain.PersonEntity; import com.demo.domain.Telephone; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value = "classpath:spring/spring-context.xml") public class PropertyEditorlJunitTest { @Resource private PersonEntity personEntity; @Test public void test() { Telephone telephone = personEntity.getTelephone(); System.out.printf("區號:%s,號碼:%s\n", telephone.getAreaCode(), telephone.getPhone()); } }
最後控制檯輸出結果:
區號:010,號碼:12345
示例1是普通spring狀況下使用PropertyEditor
的例子,那麼怎麼用在springmvc上呢?
package com.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.demo.domain.Telephone; import com.demo.mvc.component.TelephonePropertyEditor; import lombok.extern.slf4j.Slf4j; @Slf4j @Controller @RequestMapping("demo4") public class PropertyEditorDemoController { @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Telephone.class, new TelephonePropertyEditor()); } @ResponseBody @RequestMapping(method = RequestMethod.POST) public String postTelephone(@RequestParam Telephone telephone) { log.info(telephone.toString()); return telephone.toString(); } }
使用@InitBinder
註解,在WebDataBinder
對象上註冊轉換器。
這樣在訪問POST http://localhost:8080/demo4 傳表單數據 telephone = 010-12345
010-12345的字符串會自動轉換爲Telephone對象。
固然這種方式有一個缺點,該轉換器只在當前的controller下有效。
想要實現全局轉換,那就得實現WebBindingInitializer
接口
package com.demo.mvc.component; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.context.request.WebRequest; import com.demo.domain.Telephone; public class MyWebBindingInitializer implements WebBindingInitializer { @Override public void initBinder(WebDataBinder binder, WebRequest request) { binder.registerCustomEditor(Telephone.class, new TelephonePropertyEditor()); } }
在這裏能夠批量註冊轉換器。
spring-boot註冊:
package com.demo; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import com.demo.mvc.component.MyWebBindingInitializer; @SpringBootApplication public class WebMvcConfiguration extends WebMvcConfigurationSupport { @Override public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter(); adapter.setWebBindingInitializer(new MyWebBindingInitializer()); return adapter; } }
xml註冊:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.demo.mvc.component.MyWebBindingInitializer"/> </property> </bean>
p.s.:這一章介紹了這麼大篇幅的PropertyEditor
的使用,最後再說一句(不要打我哦)上述介紹的方法其實都已過期-_-。
在spring3.x後,新出了一個更強大的轉換器機制,Converter
!
那麼下一章再來說解強大的Converter
吧。
友情連接: