偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Springboot強(qiáng)大的類型轉(zhuǎn)換功能,你必須要掌握

開(kāi)發(fā) 前端
Spring3引入了一個(gè)core.convert包,它提供了一個(gè)通用類型轉(zhuǎn)換系統(tǒng)。系統(tǒng)定義一個(gè)SPI來(lái)實(shí)現(xiàn)類型轉(zhuǎn)換邏輯,定義一個(gè)API來(lái)在運(yùn)行時(shí)執(zhí)行類型轉(zhuǎn)換。

[[430214]]

環(huán)境:Springboot2.4.11

Spring3引入了一個(gè)core.convert包,它提供了一個(gè)通用類型轉(zhuǎn)換系統(tǒng)。系統(tǒng)定義一個(gè)SPI來(lái)實(shí)現(xiàn)類型轉(zhuǎn)換邏輯,定義一個(gè)API來(lái)在運(yùn)行時(shí)執(zhí)行類型轉(zhuǎn)換。在Spring容器中,你可以使用此系統(tǒng)作為PropertyEditor實(shí)現(xiàn)的替代方案,將外部化的bean屬性值字符串轉(zhuǎn)換為所需的屬性類型。你還可以在應(yīng)用程序中需要進(jìn)行類型轉(zhuǎn)換的任何位置使用公共API。

Converter SPI

實(shí)現(xiàn)類型轉(zhuǎn)換邏輯的SPI是簡(jiǎn)單且強(qiáng)類型的,如以下接口定義所示:

  1. package org.springframework.core.convert.converter; 
  2. public interface Converter<S, T> { 
  3.   T convert(S source); 

要?jiǎng)?chuàng)建自己的轉(zhuǎn)換器,需要實(shí)現(xiàn)converter接口,并將S參數(shù)化為要轉(zhuǎn)換的類型,將T參數(shù)化為要轉(zhuǎn)換的類型。如果需要將S的集合或數(shù)組轉(zhuǎn)換為T的集合或集合,還可以透明地應(yīng)用這樣的轉(zhuǎn)換器,前提是同時(shí)注冊(cè)了委托數(shù)組或集合轉(zhuǎn)換器(默認(rèn)情況下,DefaultConversionService會(huì)這樣做)。

對(duì)于每個(gè)轉(zhuǎn)換調(diào)用,保證源參數(shù)source不為null。如果轉(zhuǎn)換失敗,轉(zhuǎn)換器可能會(huì)拋出任何未檢查的異常。具體來(lái)說(shuō),它應(yīng)該拋出IllegalArgumentException以報(bào)告無(wú)效的源值。注意確保轉(zhuǎn)換器實(shí)現(xiàn)是線程安全的。

為了方便起見(jiàn),core.convert.support包中提供了幾種轉(zhuǎn)換器實(shí)現(xiàn)。其中包括從字符串到數(shù)字和其他常見(jiàn)類型的轉(zhuǎn)換器。下表顯示了StringToInteger類,它是典型的轉(zhuǎn)換器實(shí)現(xiàn):

  1. package org.springframework.core.convert.support; 
  2. final class StringToInteger implements Converter<String, Integer> { 
  3.   public Integer convert(String source) { 
  4.     return Integer.valueOf(source); 
  5.   } 

使用ConverterFactory

當(dāng)需要集中整個(gè)類層次結(jié)構(gòu)的轉(zhuǎn)換邏輯時(shí)(例如,從字符串轉(zhuǎn)換為枚舉對(duì)象時(shí)),可以實(shí)現(xiàn)ConverterFactory,如下例所示:

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

將S參數(shù)化為要轉(zhuǎn)換的類型,將R參數(shù)化為定義可轉(zhuǎn)換為的類范圍的基類型。然后實(shí)現(xiàn)getConverter(類),其中T是R的一個(gè)子類。

以StringToEnumConverterFactory為例:

  1. package org.springframework.core.convert.support; 
  2.  
  3. final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> { 
  4.  
  5.   public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) { 
  6.     return new StringToEnumConverter(targetType); 
  7.   } 
  8.   private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> { 
  9.  
  10.     private Class<T> enumType; 
  11.  
  12.     public StringToEnumConverter(Class<T> enumType) { 
  13.       this.enumType = enumType; 
  14.     } 
  15.  
  16.     public T convert(String source) { 
  17.       return (T) Enum.valueOf(this.enumType, source.trim()); 
  18.     } 
  19.   } 

自定義類型轉(zhuǎn)換

現(xiàn)在需要將接受的字符串轉(zhuǎn)換為Users對(duì)象

  1. public class Users { 
  2.   private String name ; 
  3.   private Integer age ; 

接口

  1. @GetMapping("/convert2"
  2. public Object convert2(Users users) { 
  3.   return users ;  

調(diào)用接口

Springboot強(qiáng)大的類型轉(zhuǎn)換功能你必須要掌握

如上,通過(guò)get方式users的參數(shù)通過(guò)逗號(hào)分割。接下來(lái)就是寫類型轉(zhuǎn)換器了。

  1. @SuppressWarnings({"rawtypes""unchecked"}) 
  2. public class UsersConverterFactory implements ConverterFactory<String, Users> { 
  3.  
  4.   @Override 
  5.   public <T extends Users> Converter<String, T> getConverter(Class<T> targetType) { 
  6.     return new StringToUsersConverter() ; 
  7.   } 
  8.      
  9.   private final class StringToUsersConverter<T extends Users> implements Converter<String, Users> { 
  10.     public Users convert(String source) { 
  11.       if (source == null || source.trim().length() == 0) { 
  12.         return null ; 
  13.       } 
  14.       Users user = new Users() ; 
  15.       // 下面做簡(jiǎn)單處理,不做校驗(yàn) 
  16.       String[] values = source.split(",") ; 
  17.       user.setName(values[0]) ; 
  18.       user.setAge(Integer.parseInt(values[1])); 
  19.       return user ; 
  20.     } 
  21.   } 

 注冊(cè)類型轉(zhuǎn)換器

  1. @Configuration 
  2. public class WebConfig implements WebMvcConfigurer { 
  3.  
  4.   @Override 
  5.   public void addFormatters(FormatterRegistry registry) { 
  6.     registry.addConverterFactory(new UsersConverterFactory()) ; 
  7.   } 
  8.      

編程方式使用類型轉(zhuǎn)換器

要以編程方式使用ConversionService實(shí)例,可以像對(duì)任何其他bean一樣向其注入引用。以下示例顯示了如何執(zhí)行此操作:

我們使用系統(tǒng)內(nèi)置的類型轉(zhuǎn)換器:字符串類型轉(zhuǎn)枚舉類型

  1. public enum PayStatus { 
  2.      
  3.   START, PROCESS, COMPLETE 
  4.      
  1. @RestController 
  2. @RequestMapping("/users"
  3. public class UsersController { 
  4.      
  5.   @Resource 
  6.   private ConversionService cs ; 
  7.    
  8.   @GetMapping("/convert"
  9.   public Object convert(String status) { 
  10.     boolean canConvert = cs.canConvert(String.class, PayStatus.class) ; 
  11.     return canConvert ? cs.convert(status, PayStatus.class) : "UNKNOW";  
  12.   } 
  13.    

先判斷是否能夠轉(zhuǎn)換,其實(shí)就是判斷有沒(méi)有從source到target的類型轉(zhuǎn)換器存在。

類型轉(zhuǎn)換的實(shí)現(xiàn)原理

以自定義類型轉(zhuǎn)換器為例

SpringMVC在進(jìn)行接口調(diào)用是會(huì)執(zhí)行相應(yīng)的參數(shù)解析,確定了參數(shù)解析器后會(huì)執(zhí)行轉(zhuǎn)換服務(wù)。

查找參數(shù)解析器

查找合適的HandlerMethodArgumentResolver

  1. public class InvocableHandlerMethod extends HandlerMethod { 
  2.   protected Object[] getMethodArgumentValues(...) throws Exception {   
  3.     // 查找合適的參數(shù)解析器(本例應(yīng)用的是ServletModelAttributeMethodProcessor) 
  4.     if (!this.resolvers.supportsParameter(parameter)) { 
  5.       throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); 
  6.     } 
  7.     try { 
  8.       args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); 
  9.     }       
  10.   } 

解析參數(shù)

執(zhí)行

  1. public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResolver { 
  2.   public final Object resolveArgument(...) { 
  3.     attribute = createAttribute(name, parameter, binderFactory, webRequest);     
  4.   } 
  5. public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor { 
  6.   protected final Object createAttribute(String attributeName, MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception { 
  7.     // 這里得到的是原始值 
  8.     String value = getRequestValueForAttribute(attributeName, request); 
  9.     if (value != null) { 
  10.       Object attribute = createAttributeFromRequestValue(value, attributeName, parameter, binderFactory, request); 
  11.       if (attribute != null) { 
  12.         return attribute; 
  13.       } 
  14.     } 
  15.     return super.createAttribute(attributeName, parameter, binderFactory, request); 
  16.   }   
  17.   protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,MethodParameter parameter, WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception { 
  18.     DataBinder binder = binderFactory.createBinder(request, null, attributeName); 
  19.     // ConversionService對(duì)象是在容器啟動(dòng)的時(shí)候就初始化好的 
  20.     // 在WebMvcAutoConfiguration#mvcConversionService方法中初始化。 
  21.     ConversionService conversionService = binder.getConversionService(); 
  22.     if (conversionService != null) { 
  23.       TypeDescriptor source = TypeDescriptor.valueOf(String.class); 
  24.       TypeDescriptor target = new TypeDescriptor(parameter); 
  25.       // 判斷是否有合適的類型轉(zhuǎn)換器 
  26.       if (conversionService.canConvert(source, target)) { 
  27.         // 此方法中進(jìn)行類型的轉(zhuǎn)換 
  28.         return binder.convertIfNecessary(sourceValue, parameter.getParameterType(), parameter); 
  29.       } 
  30.     } 
  31.     return null
  32.   } 

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2019-06-20 17:39:12

Android啟動(dòng)優(yōu)化

2020-04-08 17:10:03

GitHub代碼開(kāi)源

2021-12-03 18:04:06

命令 RabbitMQ Web

2019-08-07 15:20:08

Git開(kāi)源命令

2018-06-12 15:55:07

編程語(yǔ)言Java加密方式

2019-04-09 08:15:27

SEO優(yōu)化工具網(wǎng)站

2022-07-24 09:56:40

大數(shù)據(jù)技術(shù)

2019-08-06 14:54:22

Hadoop數(shù)據(jù)集海量數(shù)據(jù)

2019-12-27 15:05:11

LinuxWindowsDNS

2015-05-07 15:13:22

JS實(shí)現(xiàn)JQueryJQuery

2024-09-13 09:59:27

2023-09-13 09:20:00

日志配置Spring

2010-08-16 09:55:23

DB2數(shù)據(jù)類型

2018-01-31 22:30:05

數(shù)據(jù)科學(xué)家數(shù)據(jù)專家工程師

2018-11-28 10:00:42

React組件前端

2018-11-08 12:07:38

備份手動(dòng)磁盤

2018-09-21 11:11:34

備份離線自動(dòng)

2023-04-26 16:34:12

2019-07-31 09:06:35

Java跳槽那些事兒文章

2019-05-16 15:35:36

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)