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
吧。
友情连接: