5.盘点springmvc的常用接口之Converter(上篇)

5.盘点springmvc的常用接口之Converter(上篇)###

前言

上一章讲完了已淘汰的PropertyEditor转换器,那么这一章隆重介绍新的转换器org.springframework.core.convert.converter.Converter。(别看这接口也叫Converter,和前几章讲到的那个HttpMessageConverter不是同一个东西,千万不要搞混了-_-)。

PropertyEditor的缺点其实很明显,它只能实现从String转化到目标类型。

Converter可以实现从任意的原类型转化到目标类型。

接口说明
public interface Converter<S, T> {

	T convert(S source);
}

泛型S,T 分别为source原类型,target目标类型。

方法convert即为转换过程。

示例1

使用Converter接口重新实现上一章的转化Telephone

package com.demo.mvc.component;

import org.springframework.core.convert.converter.Converter;

import com.demo.domain.Telephone;

public class TelephoneConverter implements Converter<String, Telephone> {

	@Override
	public Telephone convert(String source) {
		if (StringUtils.hasText(source) && source.matches("^\\d+\\-\\d+$")) {
			String[] strs = source.split("\\-");
			return new Telephone(strs[0], strs[1]);
		}
		return null;
	}
}

package com.demo.controller;

import org.springframework.stereotype.Controller;
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.Person;
import com.demo.domain.Telephone;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequestMapping("demo5")
public class ConverterDemoController {

	@ResponseBody
	@RequestMapping(method = RequestMethod.POST)
	public String postTelephone(@RequestParam Telephone telephone) {
		log.info(telephone.toString());
		return telephone.toString();
	}
}

spring-boot注册:

package com.demo;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import com.demo.mvc.component.TelephoneConverter;

@SpringBootApplication
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

	@Override
	public FormattingConversionService mvcConversionService() {
		TelephoneConverter telephoneConverter = new TelephoneConverter();
		FormattingConversionService formattingConversionService = super.mvcConversionService();
		formattingConversionService.addConverter(telephoneConverter);
		return formattingConversionService;
	}
}

xml注册:

<mvc:annotation-driven conversion-service="conversionService"/>  
<bean id="conversionService"  
      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  
<property name="converters">  
  <set>  
    <bean class="com.demo.mvc.component.TelephoneConverter"/>  
  </set>  
</property>  
</bean>  
示例2

很多朋友都问过我如何把类似“2016-01-01 01:00:00”这样的字符串时间传到控制器中的Date类型。

如果不知道Converter的话,只能传字符串过去,在Controller里写硬代码转换,那就又成了垃圾代码。

Converter也可以转化表单数据到实体中各个属性。下面是的示例展示表单数据赋值进Person对象中,其中java.util.Date和Telephone默认是不能直接从字符串到对象的。

实体追加属性:

package com.demo.domain;

import java.util.Date;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class Person {

	private String firstName;

	private String lastName;

	private Telephone telephone;

	private Date registerTime;

	public Person(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return firstName + " " + lastName;
	}
}

String到java.util.Date的转换器:

package com.demo.mvc.component;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

public class StringToUtilDateConverter implements Converter<String, java.util.Date> {

	private DateFormat df;

	public StringToUtilDateConverter(String pattern) {
		df = new SimpleDateFormat(pattern);
	}

	@Override
	public Date convert(String source) {
		if (StringUtils.hasText(source)) {
			try {
				return df.parse(source);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

controller:

@ResponseBody
@RequestMapping(value = "person", method = RequestMethod.POST)
public String postPerson(Person person) {
  log.info(person.toString());
  log.info(person.getTelephone().toString());
  log.info(person.getRegisterTime().toString());
  return person.toString();
}

转换器注册略,和示例1相同。

测试访问POST http://localhost:8080/demo5

表单数据:

firstName = Bill

lastName = Gates

telephone = 010-12345

registerTime = 2016-01-01 01:00:00

Person类中的Telephone和Date都能被正确赋值。

那么问题来了,假如PropertyEditorConverter同时使用会怎么样呢?

Spring的策略是先查找PropertyEditor进行类型转换,如果没有找到相应的PropertyEditor再通过Converter进行转换。

附录:Spring内置的各种转换器

标量转换器

转换器类功能
StringToBooleanConverterString----->Boolean true: true/on/yes/1;false: false/off/no/0
ObjectToStringConverterObject----->String 调用toString方法转换
StringToNumberConverterFactoryString----->Number(如Integer、Long等)
NumberToNumberConverterFactoryNumber子类型(Integer、Long、Double等)-----> Number子类型(Integer、Long、Double等)
StringToCharacterConverterString----->java.lang.Character 取字符串第一个字符
NumberToCharacterConverterNumber子类型(Integer、Long、Double等)-----> java.lang.Character
CharacterToNumberFactoryjava.lang.Character ----->Number子类型(Integer、Long、Double等)
StringToEnumConverterFactoryString----->enum类型
EnumToStringConverterenum类型----->String 返回enum对象的name()值
StringToLocaleConverterString----->java.util.Local
PropertiesToStringConverterjava.util.Properties----->String
StringToPropertiesConverterString----->java.util.Properties

集合、数组相关转换器

转换器类功能
ArrayToCollectionConverter任意S数组---->任意T集合(List、Set)
CollectionToArrayConverter任意T集合(List、Set)---->任意S数组
ArrayToArrayConverter任意S数组<---->任意T数组
CollectionToCollectionConverter任意T集合(List、Set)<---->任意T集合(List、Set)
MapToMapConverterMap<---->Map之间的转换
ArrayToStringConverter任意S数组---->String类型
StringToArrayConverterString----->数组 默认通过“,”分割,且去除字符串的两边空格(trim)
ArrayToObjectConverter任意S数组---->任意Object的转换
ObjectToArrayConverterObject----->单元素数组
CollectionToStringConverter任意T集合(List、Set)---->String类型
StringToCollectionConverterString----->集合(List、Set)
CollectionToObjectConverter任意T集合---->任意Object的转换
ObjectToCollectionConverterObject----->单元素集合

默认(fallback)转换器之前的转换器不能转换时调用

转换器类功能
ObjectToObjectConverterObject(S)----->Object(T)首先尝试valueOf进行转换、没有则尝试new 构造器(S)
IdToEntityConverterId(S)----->Entity(T)
FallbackObjectToStringConverterObject----->String 最终转换方法,调用toString()

p.s.:Spring自带了这么多的转换器,从而可以自动化地转换类型。开发者无需再实现低级的普通类型间的转换,不然像String->Integer,String->Boolean这种,每个都要开发者自己实现,那不是要吐了。关于Converter的介绍还没有完,在下一章将介绍更加深入的使用Converter

友情链接:

盘点springmvc的常用接口目录

转载于:https://my.oschina.net/sugarZone/blog/705376

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值