5.盤點springmvc的經常使用接口之Converter(上篇)

5.盤點springmvc的經常使用接口之Converter(上篇)###

前言

上一章講完了已淘汰的PropertyEditor轉換器,那麼這一章隆重介紹新的轉換器org.springframework.core.convert.converter.Converter。(別看這接口也叫Converter,和前幾章講到的那個HttpMessageConverter不是同一個東西,千萬不要搞混了-_-)。java

PropertyEditor的缺點其實很明顯,它只能實現從String轉化到目標類型。web

Converter能夠實現從任意的原類型轉化到目標類型。spring

接口說明

public interface Converter<S, T> {

	T convert(S source);
}

泛型S,T 分別爲source原類型,target目標類型。數組

方法convert即爲轉換過程。mvc

示例1

使用Converter接口從新實現上一章的轉化Telephoneapp

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註冊:dom

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註冊:ide

<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類型。spring-boot

若是不知道Converter的話,只能傳字符串過去,在Controller裏寫硬代碼轉換,那就又成了垃圾代碼。post

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內置的各類轉換器

標量轉換器

轉換器類 功能
StringToBooleanConverter String----->Boolean true: true/on/yes/1;false: false/off/no/0
ObjectToStringConverter Object----->String 調用toString方法轉換
StringToNumberConverterFactory String----->Number(如Integer、Long等)
NumberToNumberConverterFactory Number子類型(Integer、Long、Double等)-----> Number子類型(Integer、Long、Double等)
StringToCharacterConverter String----->java.lang.Character 取字符串第一個字符
NumberToCharacterConverter Number子類型(Integer、Long、Double等)-----> java.lang.Character
CharacterToNumberFactory java.lang.Character ----->Number子類型(Integer、Long、Double等)
StringToEnumConverterFactory String----->enum類型
EnumToStringConverter enum類型----->String 返回enum對象的name()值
StringToLocaleConverter String----->java.util.Local
PropertiesToStringConverter java.util.Properties----->String
StringToPropertiesConverter String----->java.util.Properties

集合、數組相關轉換器

轉換器類 功能
ArrayToCollectionConverter 任意S數組---->任意T集合(List、Set)
CollectionToArrayConverter 任意T集合(List、Set)---->任意S數組
ArrayToArrayConverter 任意S數組<---->任意T數組
CollectionToCollectionConverter 任意T集合(List、Set)<---->任意T集合(List、Set)
MapToMapConverter Map<---->Map之間的轉換
ArrayToStringConverter 任意S數組---->String類型
StringToArrayConverter String----->數組 默認經過「,」分割,且去除字符串的兩邊空格(trim)
ArrayToObjectConverter 任意S數組---->任意Object的轉換
ObjectToArrayConverter Object----->單元素數組
CollectionToStringConverter 任意T集合(List、Set)---->String類型
StringToCollectionConverter String----->集合(List、Set)
CollectionToObjectConverter 任意T集合---->任意Object的轉換
ObjectToCollectionConverter Object----->單元素集合

默認(fallback)轉換器以前的轉換器不能轉換時調用

轉換器類 功能
ObjectToObjectConverter Object(S)----->Object(T)首先嚐試valueOf進行轉換、沒有則嘗試new 構造器(S)
IdToEntityConverter Id(S)----->Entity(T)
FallbackObjectToStringConverter Object----->String 最終轉換方法,調用toString()

p.s.:Spring自帶了這麼多的轉換器,從而能夠自動化地轉換類型。開發者無需再實現低級的普通類型間的轉換,否則像String->Integer,String->Boolean這種,每一個都要開發者本身實現,那不是要吐了。關於Converter的介紹尚未完,在下一章將介紹更加深刻的使用Converter

友情連接:

盤點springmvc的經常使用接口目錄

相關文章
相關標籤/搜索