读书人

Spring3 Web MVC下的数据类型转换(第

发布时间: 2012-06-29 15:48:47 作者: rapoo

Spring3 Web MVC下的数据类型转换(第一篇)——《跟我学Spring3 Web MVC》抢先看

?

基于spring-framework-3.1.1.RELEASE

7.1、简介


?

<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %><%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

//1、格式化单个命令/表单对象的值(好像比较麻烦,真心没有好办法)<spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind>?

//2、<spring:eval>标签,自动调用ConversionService并选择相应的Converter SPI进行格式化展示<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval>

?如上代码能工作的前提是在RequestMappingHandlerMapping配置了ConversionServiceExposingInterceptor,它的作用是暴露conversionService到请求中以便如<spring:eval>标签使用。

?

//3、通过form标签,内部的表单标签会自动调用命令/表单对象属性对应的PropertyEditor进行格式化显示<form:form commandName="dataBinderTest">    <form:input path="phoneNumber"/><!-- 如果出错会显示错误之前的数据而不是空 --></form:form>
?
//4、显示验证失败后的错误信息<form:errors></form:errors>

?接下来我们就详细学习一下这些知识吧。

package cn.javass.chapter7.web.controller;//省略import@Controllerpublic class DataBinderTestController { @RequestMapping(value = "/dataBind") public String test(DataBinderTestModel command) { //输出command对象看看是否绑定正确System.out.println(command);model.addAttribute("dataBinderTest", command);return "bind/success";}}

?

<bean name="code">@InitBinder//此处的参数也可以是ServletRequestDataBinder类型public void initBinder(WebDataBinder binder) throws Exception {//注册自定义的属性编辑器//1、日期DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");CustomDateEditor dateEditor = new CustomDateEditor(df, true);//表示如果命令对象有Date类型的属性,将使用该属性编辑器进行类型转换binder.registerCustomEditor(Date.class, dateEditor);//自定义的电话号码编辑器(和【4.16.1、数据类型转换】一样)binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor());}

?<bean src="/img/2012/06/25/0523235398.jpg">

package org.springframework.core.convert.converter;public interface Converter<S, T> { //① S是源类型 T是目标类型T convert(S source); //② 转换S类型的source到T目标类型的转换方法}

?示例:请参考cn.javass.chapter7.converter.support.StringToPhoneNumberConverter转换器,用于将String--->PhoneNumberModel。

package org.springframework.core.convert.converter;public interface GenericConverter {Set<ConvertiblePair> getConvertibleTypes();Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);}

getConvertibleTypes:指定了可以转换的目标类型对;

package org.springframework.core.convert.converter;public interface ConditionalGenericConverter extends GenericConverter {boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);}

?matches:用于判断sourceType和targetType类型之间能否进行类型转换。

package org.springframework.core.convert.converter;public interface ConverterFactory<S, R> {<T extends R> Converter<S, T> getConverter(Class<T> targetType);}

?S:源类型;R目标类型的父类型;T:目标类型,且是R类型的子类型;


?一共有如下两种接口:

package org.springframework.core.convert.converter;public interface ConverterRegistry {void addConverter(Converter<?, ?> converter);void addConverter(Class<?> sourceType, Class<?> targetType, Converter<?, ?> converter);void addConverter(GenericConverter converter);void addConverterFactory(ConverterFactory<?, ?> converterFactory);void removeConvertible(Class<?> sourceType, Class<?> targetType);}

?可以注册:Converter实现,GenericConverter实现,ConverterFactory实现。

package org.springframework.core.convert;public interface ConversionService {boolean canConvert(Class<?> sourceType, Class<?> targetType);boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);<T> T convert(Object source, Class<T> targetType);Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);}

?convert:将源对象转换为目标类型的目标对象。

package cn.javass.chapter7.web.controller.support.converter;//省略importpublic class StringToPhoneNumberConverter implements Converter<String, PhoneNumberModel> {Pattern pattern = Pattern.compile("^(\\d{3,4})-(\\d{7,8})$");@Overridepublic PhoneNumberModel convert(String source) {if(!StringUtils.hasLength(source)) {//①如果source为空 返回nullreturn null;}Matcher matcher = pattern.matcher(source);if(matcher.matches()) {//②如果匹配 进行转换PhoneNumberModel phoneNumber = new PhoneNumberModel();phoneNumber.setAreaCode(matcher.group(1));phoneNumber.setPhoneNumber(matcher.group(2));return phoneNumber;} else {//③如果不匹配 转换失败throw new IllegalArgumentException(String.format("类型转换失败,需要格式[010-12345678],但格式是[%s]", source));}}}?

?

@Testpublic void testStringToPhoneNumberConvert() {DefaultConversionService conversionService = new DefaultConversionService();conversionService.addConverter(new StringToPhoneNumberConverter());String phoneNumberStr = "010-12345678";PhoneNumberModel phoneNumber = conversionService.convert(phoneNumberStr, PhoneNumberModel.class);Assert.assertEquals("010", phoneNumber.getAreaCode());}

@Testpublic void testOtherConvert() {DefaultConversionService conversionService = new DefaultConversionService();//"1"--->true(字符串“1”可以转换为布尔值true)Assert.assertEquals(Boolean.valueOf(true), conversionService.convert("1", Boolean.class));//"1,2,3,4"--->List(转换完毕的集合大小为4)Assert.assertEquals(4, conversionService.convert("1,2,3,4", List.class).size());}

?其他类型转换器使用也是类似的,此处不再重复。

7.2.2.4、集成到Spring Web MVC环境

<!-- ①注册ConversionService --><bean id="conversionService" name="code"><!-- ②使用ConfigurableWebBindingInitializer注册conversionService --><bean id="webBindingInitializer" ref="conversionService"/></bean>

?此处我们通过ConfigurableWebBindingInitializer绑定初始化器进行ConversionService的注册;

<bean ref="webBindingInitializer"/></bean>

?通过如上配置,我们就完成了Spring3.0的类型转换系统与Spring Web MVC的集成。此时可以启动服务器输入之前的URL测试了。

,估计我得叫你姐 ,估计我得叫你姐

。。。
其实我是男的,头像那个是我老婆。 ,估计我得叫你姐

。。。
其实我是男的,头像那个是我老婆。
……………… 哈哈哈哈,那得喊你哥 5 楼 偶尔玩玩 2012-05-03 楼主辛苦了,继续加油 6 楼 jinnianshilongnian 2012-05-03 偶尔玩玩 写道 楼主辛苦了,继续加油
谢谢

读书人网 >Web前端

热点推荐