自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Springboot強大的類型轉換功能,你必須要掌握

開發(fā) 前端
Spring3引入了一個core.convert包,它提供了一個通用類型轉換系統(tǒng)。系統(tǒng)定義一個SPI來實現類型轉換邏輯,定義一個API來在運行時執(zhí)行類型轉換。

[[430214]]

環(huán)境:Springboot2.4.11

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

Converter SPI

實現類型轉換邏輯的SPI是簡單且強類型的,如以下接口定義所示:

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

要創(chuàng)建自己的轉換器,需要實現converter接口,并將S參數化為要轉換的類型,將T參數化為要轉換的類型。如果需要將S的集合或數組轉換為T的集合或集合,還可以透明地應用這樣的轉換器,前提是同時注冊了委托數組或集合轉換器(默認情況下,DefaultConversionService會這樣做)。

對于每個轉換調用,保證源參數source不為null。如果轉換失敗,轉換器可能會拋出任何未檢查的異常。具體來說,它應該拋出IllegalArgumentException以報告無效的源值。注意確保轉換器實現是線程安全的。

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

  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

當需要集中整個類層次結構的轉換邏輯時(例如,從字符串轉換為枚舉對象時),可以實現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參數化為要轉換的類型,將R參數化為定義可轉換為的類范圍的基類型。然后實現getConverter(類),其中T是R的一個子類。

以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.   } 

自定義類型轉換

現在需要將接受的字符串轉換為Users對象

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

接口

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

調用接口

Springboot強大的類型轉換功能你必須要掌握

如上,通過get方式users的參數通過逗號分割。接下來就是寫類型轉換器了。

  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.       // 下面做簡單處理,不做校驗 
  16.       String[] values = source.split(",") ; 
  17.       user.setName(values[0]) ; 
  18.       user.setAge(Integer.parseInt(values[1])); 
  19.       return user ; 
  20.     } 
  21.   } 

 注冊類型轉換器

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

編程方式使用類型轉換器

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

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

  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.    

先判斷是否能夠轉換,其實就是判斷有沒有從source到target的類型轉換器存在。

類型轉換的實現原理

以自定義類型轉換器為例

SpringMVC在進行接口調用是會執(zhí)行相應的參數解析,確定了參數解析器后會執(zhí)行轉換服務。

查找參數解析器

查找合適的HandlerMethodArgumentResolver

  1. public class InvocableHandlerMethod extends HandlerMethod { 
  2.   protected Object[] getMethodArgumentValues(...) throws Exception {   
  3.     // 查找合適的參數解析器(本例應用的是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.   } 

解析參數

執(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對象是在容器啟動的時候就初始化好的 
  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.       // 判斷是否有合適的類型轉換器 
  26.       if (conversionService.canConvert(source, target)) { 
  27.         // 此方法中進行類型的轉換 
  28.         return binder.convertIfNecessary(sourceValue, parameter.getParameterType(), parameter); 
  29.       } 
  30.     } 
  31.     return null
  32.   } 

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2019-06-20 17:39:12

Android啟動優(yōu)化

2021-12-03 18:04:06

命令 RabbitMQ Web

2020-04-08 17:10:03

GitHub代碼開源

2018-06-12 15:55:07

編程語言Java加密方式

2019-08-07 15:20:08

Git開源命令

2022-07-24 09:56:40

大數據技術

2019-04-09 08:15:27

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

2015-05-07 15:13:22

JS實現JQueryJQuery

2019-12-27 15:05:11

LinuxWindowsDNS

2019-08-06 14:54:22

Hadoop數據集海量數據

2024-09-13 09:59:27

2023-09-13 09:20:00

日志配置Spring

2010-08-16 09:55:23

DB2數據類型

2018-01-31 22:30:05

數據科學家數據專家工程師

2018-09-21 11:11:34

備份離線自動

2018-11-08 12:07:38

備份手動磁盤

2018-11-28 10:00:42

React組件前端

2019-05-16 15:35:36

2021-02-04 13:10:32

歸并排序算法

2019-07-31 09:06:35

Java跳槽那些事兒文章
點贊
收藏

51CTO技術棧公眾號