Spring Boot中如何使用Convert接口實現(xiàn)類型轉(zhuǎn)換器
使用Convert接口實現(xiàn)類型轉(zhuǎn)換器
在Spring3中引入了一個Converter接口,它支持從一個Object轉(zhuǎn)為另一個Object。除了Converter接口之外,實現(xiàn)ConverterFactory接口和GenericConverter接口也可以實現(xiàn)我們自己的類型轉(zhuǎn)換邏輯。
Converter接口
首先看看Converter接口的定義
public interface Converter<S, T> {
T convert(S source);
}
可以看到這個接口是使用了泛型的,S表示原類型,T表示目標(biāo)類型,然后里面定義了一個convert方法,將原類型對象作為參數(shù)傳入進(jìn)行轉(zhuǎn)換之后返回目標(biāo)類型對象。
下面在Spring Boot中使用Converter接口來實現(xiàn)將String類型分別轉(zhuǎn)換為Data,自定義對象和List<自定義對象>。
添加依賴
添加spring-boot-starter-web依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
實體類
1.User類
public class User {
private long id;
//用戶名
private String name;
//出生日期
private Date birth;
//關(guān)聯(lián)用戶
private User linkUser;
//喜歡的文章
private List<Article> favArticles=new ArrayList<>();
//下面省略Getter和Setter方法
2.Article類
public class Article {
//文章id
private long artId;
//文章名
private String artName;
//下面省略Getter和Setter方法
}
配置類型轉(zhuǎn)化器
下面三個類都需要添加@Component注解,否則不能生效。并實現(xiàn)Spring提供的org.springframework.core.convert.converter.Converter接口,重寫其中的convert()方法 ,方法中寫自己的轉(zhuǎn)換邏輯。
1.定義全局日期轉(zhuǎn)換器
@Component
public class DateConvert implements Converter<String,Date> {
//日期格式
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date convert(String s) {
if (s!=null&&!"".equals(s)){
try {
//解析參數(shù)
Date date=sdf.parse(s);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}
2.定義全局對象轉(zhuǎn)換器
這里使用Jackson的ObjectMapper類的readValue()函數(shù)實現(xiàn)將Json字符串反序列化為Java對象
@Component
public class ObjectConvert implements Converter<String,User> {
@Override
public User convert(String s) {
ObjectMapper objectMapper=new ObjectMapper();
if (s!=null&&!"".equals(s)){
try {
User user=objectMapper.readValue(s,User.class);
return user;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return null;
}
}
3.定義全局List類型轉(zhuǎn)換器
這里使用Jackson的ObjectMapper類的readValue()函數(shù)實現(xiàn)將Json字符串反序列化為 List
@Component
public class StringToListController implements Converter<String, List<Article>> {
ObjectMapper objectMapper=new ObjectMapper();
@Override
public List<Article> convert(String s) {
List<Article> list=null;
try {
list=objectMapper.readValue(s, new TypeReference<List<Article>>() {
});
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return list;
}
}
控制器
這里注意使用produces設(shè)置返回數(shù)據(jù)的類型為json,consumes設(shè)置提交內(nèi)容的類型為:application/x-www-form-urlencoded。
application/x-www-form-urlencoded作用:將鍵值對的參數(shù)用&連接起來,如果有空格,將空格轉(zhuǎn)換為+加號;有特殊符號,將特殊符號轉(zhuǎn)換為ASCII HEX值。
@RestController
public class HelloController {
@GetMapping("hello")
public Date getDate(Date birth){
System.out.println(birth);
return birth;
}
@PostMapping(value="showUser",produces="application/json",
consumes = "application/x-www-form-urlencoded")
public User showUser(User user){
return user;
}
}
測試
在Postman中進(jìn)行測試,注意以下設(shè)置:POST請求 -> Body -> x-www-form-urlencoded。在Body中輸入?yún)?shù)進(jìn)行測試。
因為參數(shù)中有Json類型參數(shù),如果直接使用Params下進(jìn)行發(fā)送數(shù)據(jù),會出現(xiàn)請求參數(shù)異常錯誤。

測試結(jié)果:

Converter使用及其原理
在Spring MVC開發(fā)中,我們可以很方便的使用Converter來實現(xiàn)對請求參數(shù)的處理,比如字符串去空,日期格式化等。
配置文件中對Converter的引用
<!-- 屬性編輯器 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.xxx.common.converter.StringTrimConverter" />
<bean class="com.xxx.common.converter.DateConverter" />
<bean class="com.xxx.common.converter.DatetimeConverter" />
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService">
如上代碼,我們配置了三種類型的Converter。
以字符串去空為例
import org.springframework.core.convert.converter.Converter;
/**
* 去除前后空格
* @author
*
*/
public class StringTrimConverter implements Converter<String, String> {
public String convert(String source) {
//如果源字符串不為空則進(jìn)行轉(zhuǎn)換
if(source != null){
//去除源字符串前后空格
source = source.trim();
if(source.equals("")){
source = null;
}
}
return source;
}
}
配置好以上內(nèi)容,即可在我們的請求中實現(xiàn)字符串自動去空格。
明白使用其實很簡單,我們可以看下在Spring的底層,具體是如何實現(xiàn)Converter的。我們以字符串去空的代碼為例。
以上代碼,首先實現(xiàn)了Converter接口
我們查看Converter接口的源碼
/**
* A converter converts a source object of type S to a target of type T.
* Implementations of this interface are thread-safe and can be shared.
*
* <p>Implementations may additionally implement {@link ConditionalConverter}.
*
* @author Keith Donald
* @since 3.0
* @see ConditionalConverter
* @param <S> The source type
* @param <T> The target type
*/
public interface Converter<S, T> {
/**
* Convert the source of type S to target type T.
* @param source the source object to convert, which must be an instance of S
* @return the converted object, which must be an instance of T
* @throws IllegalArgumentException if the source could not be converted to the desired target type
*/
T convert(S source);
}
通過JavaDoc我們可以看到,實現(xiàn)該接口,可以使我們將S類型的對象轉(zhuǎn)換為T類型。那么對應(yīng)的我們對于Date類型的轉(zhuǎn)換,就可寫為如下代碼:
public class DateConverter implements Converter
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
該類的對象,繼續(xù)查看對應(yīng)改類的源碼,以及對應(yīng)的JavaDoc。我們可以在該類的Doc中看到如下描述:
* <p>Like all {@code FactoryBean} implementations, this class is suitable for
* use when configuring a Spring application context using Spring {@code <beans>}
* XML. When configuring the container with
* {@link org.springframework.context.annotation.Configuration @Configuration}
* classes, simply instantiate, configure and return the appropriate
* {@code FormattingConversionService} object from a
* {@link org.springframework.context.annotation.Bean @Bean} method.
該類適用于適用XML構(gòu)建Spring應(yīng)用。
我們查看對應(yīng)的成員變量:
public class FormattingConversionServiceFactoryBean
implements FactoryBean<FormattingConversionService>, EmbeddedValueResolverAware, InitializingBean {
private Set<?> converters;
private Set<?> formatters;
private Set<FormatterRegistrar> formatterRegistrars;
private boolean registerDefaultFormatters = true;
private StringValueResolver embeddedValueResolver;
private FormattingConversionService conversionService;
在配置XML時,我們主要配置了集合類的converters,該類比較重要的方法如下:
@Override
public void afterPropertiesSet() {
this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);
ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
registerFormatters();
}
該方法實現(xiàn)了對conversionService中增減我們對應(yīng)的格式化器。
在Spring啟動時,注冊轉(zhuǎn)換器 時會進(jìn)入afterPropertiesSet 方法。在該方法中,我們可以看到Spring以HashSet來存儲對應(yīng)的converters。在ConversionServiceFactory中,判斷不同的轉(zhuǎn)換器,并進(jìn)行注冊。
public static void registerConverters(Set<?> converters, ConverterRegistry registry) {
if (converters != null) {
for (Object converter : converters) {
if (converter instanceof GenericConverter) {
registry.addConverter((GenericConverter) converter);
}
else if (converter instanceof Converter<?, ?>) {
registry.addConverter((Converter<?, ?>) converter);
}
else if (converter instanceof ConverterFactory<?, ?>) {
registry.addConverterFactory((ConverterFactory<?, ?>) converter);
}
else {
throw new IllegalArgumentException("Each converter object must implement one of the " +
"Converter, ConverterFactory, or GenericConverter interfaces");
}
}
}
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
tomcat啟動完成執(zhí)行 某個方法 定時任務(wù)(Spring)操作
這篇文章主要介紹了tomcat啟動完成執(zhí)行 某個方法 定時任務(wù)(Spring)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Eclipse運(yùn)行android項目報錯Unable to build: the file dx.jar was not
今天小編就為大家分享一篇關(guān)于Eclipse運(yùn)行android項目報錯Unable to build: the file dx.jar was not loaded from the SDK folder的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
java利用CompletionService保證任務(wù)先完成先獲取到執(zhí)行結(jié)果
這篇文章主要為大家詳細(xì)介紹了java如何利用CompletionService來保證任務(wù)先完成先獲取到執(zhí)行結(jié)果,文中的示例代碼講解詳細(xì),需要的可以參考下2023-08-08
SpringBoot整合kaptcha實現(xiàn)圖片驗證碼功能
這篇文章主要介紹了SpringBoot整合kaptcha實現(xiàn)圖片驗證碼功能,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07
SpringBoot集成Redis實現(xiàn)消息隊列的方法
這篇文章主要介紹了SpringBoot集成Redis實現(xiàn)消息隊列的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
java模擬TCP通信實現(xiàn)客戶端上傳文件到服務(wù)器端
這篇文章主要為大家詳細(xì)介紹了java模擬TCP通信實現(xiàn)客戶端上傳文件到服務(wù)器端,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-10-10

