广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Spring中自定义数据类型转换的方法详解
  • 875
分享到

Spring中自定义数据类型转换的方法详解

2024-04-02 19:04:59 875人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录类型转换服务实现Converter接口实现ConverterFactory接口实现GenericConverter接口环境:spring5.3.12.RELEASE。 Sprin

环境:spring5.3.12.RELEASE。

Spring 3引入了一个core.onvert包,提供一个通用类型转换系统。系统定义了一个SPI来实现类型转换逻辑,以及一个api来在运行时执行类型转换。在Spring容器中,可以使用这个系统作为PropertyEditor实现的替代,将外部化的bean属性值字符串转换为所需的属性类型。还可以在应用程序中需要类型转换的任何地方使用公共API。

类型转换服务

ConversionService 类型转换服务的接口。

public interface ConversionService {
  // 判断是否能进行转换
  boolean canConvert(Class<?> sourceType, Class<?> targetType);
  boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
  // 进行类型转换
  <T> T convert(Object source, Class<T> targetType);
  Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}

在大多数情况下我们应该实现。

ConfigurableConversionService可配置的类型转换服务接口。该接口整合ConversionService的所有操作和ConverterReGIStry接口的相关操作,可对具体的转换进行增删。在应用程序上下文引导代码中处理ConfigurableEnvironment实例时,后者特别有用。

ConfigurableConversionService接口。

public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {
}

Spring提供了GenericConversionService 实现类;该类适合在大多数环境中使用的基本 ConversionService实现。通过

ConfigurableConversionService接口间接实现ConverterRegistry作为注册API。该类没有提供默认的类型转换功能,需要我们自己添加转换接口。

示例:

GenericConversionService GCs = new GenericConversionService() ;
Long result = gcs.convert("10", Long.class) ;
System.out.println(result) ;

以上代码运行将报错:

Exception in thread "main" org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.lang.Long]
  at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
  at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
  at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
  at com.pack.main.conversion.GenericConversionServiceMain.main(GenericConversionServiceMain.java:9)

没有转换接口发现错误。

FORMattingConversionService 类是GenericConversionService 子类对象,主要作用就是增加了格式化功能(还是类型转换的一种表现),该类提供了 Printer和Parser的支持,可对对象进行打印展示及将源数据解析成目标对象,示例:

FormattingConversionService fcs = new FormattingConversionService() ;
fcs.addParser(new Parser<Teacher>() {
  @Override
  public Teacher parse(String text, Locale locale) throws ParseException {
    String[] t = text.split("\\|") ;
    return new Teacher(t[0], Integer.valueOf(t[1])) ;
  }
});
System.out.println(fcs.convert("张晶晶|26", Teacher.class)) ;

这里的addParser方法最后还是将Parser转换为GenericConverter。

将对象转换为可读的信息,示例:

FormattingConversionService fcs = new FormattingConversionService() ;
fcs.addPrinter(new Printer<Teacher>() {
  @Override
  public String print(Teacher object, Locale locale) {
    return "【 name = " + object.getName() + ", age = " + object.getAge() + "】" ;
  }
});
System.out.println(fcs.convert(new Teacher("张晶晶", 26), String.class)) ;

以上介绍的类型转换服务默认没有任何的类型转换能力,都需要我们自定义添加,在Spring中还提供了DefaultConversionService 和 WEBConversionService。

通过名称知道WebConversionService 针对Web项目,但是你也是可以在非Web项目中使用。这里我就介绍DefaultConversionService 。先看示例:

DefaultConversionService dcs = new DefaultConversionService() ;
Long result = dcs.convert("10", Long.class) ;
Date date = dcs.convert("2022-07-01", Date.class) ;
System.out.println(result) ;
System.out.println(date) ;

上面两个类型的转换都能成功,为什么呢?因为DefaultConversionService 内部已经帮我们注册了很多的类型转换,源码

public class DefaultConversionService extends GenericConversionService {
  public DefaultConversionService() {
    aDDDefaultConverters(this);
  }
  public static void addDefaultConverters(ConverterRegistry converterRegistry) {
    addScalarConverters(converterRegistry);
    // 该方法中还注册了很多集合,流数据类型的转换功能,详细查看源码
    addCollectionConverters(converterRegistry);
    converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
    converterRegistry.addConverter(new StringToTimeZoneConverter());
    converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
    converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

    converterRegistry.addConverter(new ObjectToObjectConverter());
    converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
   converterRegistry.addConverter(new FallbackObjectToStringConverter());
   converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
  }
}

通常我们一般都是使用DefaultConversionService。

在Web环境下默认使用的WebConversionService ,这里以SpringBoot为例,源码如下:

public class WebmvcAutoConfiguration {
  public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    @Bean
    @Override
    public FormattingConversionService mvcConversionService() {
      Format format = this.mvcProperties.getFormat();
      WebConversionService conversionService = new WebConversionService(new DateTimeFormatters().dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
      addFormatters(conversionService);
      return conversionService;
    }    
  }
}

WebConversionService的继承关系

public class WebConversionService extends DefaultFormattingConversionService {}
public class DefaultFormattingConversionService extends FormattingConversionService {}
public class FormattingConversionService extends GenericConversionService
  implements FormatterRegistry, EmbeddedValueResolverAware {
}

Spring还提供了一个ConversionServiceFactoryBean来注册我们自定义的类型转换。

public class ConversionServiceFactoryBean implements FactoryBean<ConversionService>, InitializingBean {
  private Set<?> converters;
  private GenericConversionService conversionService;
  public void setConverters(Set<?> converters) {
    this.converters = converters;
  }
  @Override
  public void afterPropertiesSet() {
    this.conversionService = createConversionService();
    ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
  }
  protected GenericConversionService createConversionService() {
    return new DefaultConversionService();
  }
  @Override
  public ConversionService getObject() {
    return this.conversionService;
  }
  @Override
  public Class<? extends ConversionService> getObjectType() {
    return GenericConversionService.class;
  }
  @Override
  public boolean isSingleton() {
    return true;
  }
}

我们可以定个该Bean,然后注入converters属性值。

@Bean
public ConversionServiceFactoryBean conversionService() {
  ConversionServiceFactoryBean factory = new ConversionServiceFactoryBean() ;
  // 自定义的类型转换
  factory.setConverters(...) ;
  return factory ;
}

Spring的类型转换服务是不是挺简单?接下来介绍Spring提供的各种自定义类型转换方式。

接下来我们都是以示例为主。

实现Converter接口

Converter接口。

@FunctionalInterface
public interface Converter<S, T> {
  T convert(S source);
}

自定义Converter接口,我们使用匿名内部类实现。

DefaultConversionService cs = new DefaultConversionService();
// 自定义类型转换器,当有了ConversionService完全可以替代PropertyEditor
cs.addConverter(new Converter<String, Users>() {
  public Users convert(String source) {
    String[] temp = source.split("\\|") ;
    return new Users(temp[0], Integer.parseInt(temp[1])) ;
  }
}) ;
Users users = cs.convert("张三|100", Users.class) ;
System.out.println(users) ;

实现ConverterFactory接口

当你需要集中整个类层次结构的转换逻辑时(例如,当从String转换到Enum对象时),你可以实现ConverterFactory。也就是有继承关系的类型转换。

ConverterFactory接口。

public interface ConverterFactory<S, R> {
  <T extends R> Converter<S, T> getConverter(Class<T> targetType);
}

自定义工厂类。

public class EnvObjectConvert implements ConverterFactory<String, EnvObject> {
  @Override
  public <T extends EnvObject> Converter<String, T> getConverter(Class<T> targetType) {
    return new EnvConvert<T>();
  }
  private class EnvConvert<T extends EnvObject> implements Converter<String, T> {
    @Override
    public T convert(String source) {
      String[] temp = source.split("\\|") ;
      return (T) new EnvObject(temp[0], Integer.valueOf(temp[1])) ;
    }
  }
}

实现GenericConverter接口

当你需要复杂的Converter实现时,请考虑使用GenericConverter接口。与Converter相比,GenericConverter具有更灵活但强类型较少的签名,因此它支持在多个源类型和目标类型之间进行转换。此外,GenericConverter提供了可用的源和目标字段上下文,你可以在实现转换逻辑时使用它们。这样的上下文允许通过字段注释或在字段签名上声明的泛型信息驱动类型转换。下面的清单显示了GenericConverter的接口定义:

GenericConverter接口。

public interface GenericConverter {
  Set<ConvertiblePair> getConvertibleTypes();
  Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}

自定义GenericConverter。

public class CustomGenericConverter implements GenericConverter {
  @Override
  public Set<ConvertiblePair> getConvertibleTypes() {
    // 这里我们可以定义多组的类型转换关系
    ConvertiblePair teacherPair = new ConvertiblePair(String.class, Teacher.class) ;
    ConvertiblePair studentPair = new ConvertiblePair(String.class, Student.class) ;
    Set<ConvertiblePair> pairs = new HashSet<>() ;
    pairs.add(teacherPair) ;
    pairs.add(studentPair) ;
    return pairs ;
  }
  @Override
  public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
    // 下面分别看到不同的类型做不同的处理
    String str = null ;
    if (sourceType.getObjectType() == String.class) {
      str = (String) source ; 
    }
    if (targetType.getObjectType() == Teacher.class) {
      String[] t = str.split("\\|") ;
      return new Teacher(t[0], Integer.valueOf(t[1])) ;
    }
    if (targetType.getObjectType() == Student.class) {
      String[] t = str.split("\\|") ;
      return new Student(t[0], t[1]) ;
    }
    return null ;
  }
}

以上就是Spring中自定义数据类型转换的方法详解的详细内容,更多关于Spring数据类型转换的资料请关注编程网其它相关文章!

--结束END--

本文标题: Spring中自定义数据类型转换的方法详解

本文链接: https://www.lsjlt.com/news/151953.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring中自定义数据类型转换的方法详解
    目录类型转换服务实现Converter接口实现ConverterFactory接口实现GenericConverter接口环境:Spring5.3.12.RELEASE。 Sprin...
    99+
    2022-11-13
  • C++自定义数据类型方法详情
    目录1、typedef声明2、枚举类型enum1、typedef声明 typedef用于给已有的类型一个新的名字,这个新的名字可以是自己定义的, 其语法为: typedef 现有类型...
    99+
    2022-11-13
  • Spring MVC 自定义数据转换器的思路案例详解
    数据转换器是指将客户端 http 请求中的参数转换为业务方法中定义的形参,自定义表示开发者可以自主设计转换模式,HandlerAdapter 已经提供了通用的转换,比如将 Strin...
    99+
    2022-11-12
  • C#中怎么自定义类型转换函数
    C#中怎么自定义类型转换函数,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。/// <summary>  /// 将字符型...
    99+
    2023-06-18
  • 详解Python中数据类型的转换
    目录一. 转换数据类型的作用二. 转换数据类型的函数三. 快速体验四. 实验总结一. 转换数据类型的作用 问:input()接收用户输入的数据都是字符串类型,如果用户输入1,想得到整...
    99+
    2023-03-15
    Python数据类型转换 Python数据类型
  • Spring中的类型转换器怎么定义使用
    这篇文章主要讲解了“Spring中的类型转换器怎么定义使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring中的类型转换器怎么定义使用”吧!1.类型转换器作用类型的转换赋值2.自定义...
    99+
    2023-07-04
  • 浅谈让@Value更方便的Spring自定义转换类
    目录一、万能的字符串二、自定义转换类三、总结一、万能的字符串 当然,任何时候都可以使用字符串作为属性的值,从配置文件里读取出来,如下: 配置文件内容为: pkslow.admin=...
    99+
    2022-11-12
  • JavaScript数据类型的转换详解
    目录数据类型的转换概述强制转换Number()String()Boolean()自动转换自动转换为布尔值自动转换为字符串自动转换为数值数据类型的转换 概述 JavaScript是一种...
    99+
    2022-12-22
    JavaScript数据类型转换 JavaScript数据类型 JS 数据类型转换
  • java数据类型转换的方法
    这篇文章主要讲解了“java数据类型转换的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java数据类型转换的方法”吧!自动类型转换:主要指小类型到大类型的转换。 即强制类型转换:主要指...
    99+
    2023-06-19
  • python数据类型的转换方法
    这篇文章主要介绍“python数据类型的转换方法”,在日常操作中,相信很多人在python数据类型的转换方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python数据类型的转换方法”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • 详解Go语言中的数据类型及类型转换
    目录1、基本数据类型2、基础数据类型转换3、基本数据类型转为字符串4、strconv的使用5、字符串转为基础类型1、基本数据类型 数据类型有很多,先研究一下基础的,例如:布尔型、数字...
    99+
    2022-11-13
  • Python 变量的定义和数据类型的转换
    变量 变量的定义 基本语法:变量名 = 值 变量名是给对象贴一个用于访问的标签,给对象绑定名字的过程也称为赋值,赋值符号 “=” 变量名自定义,要满足标识符命名规则。 Python中,不需要事先...
    99+
    2023-09-15
    python 变量 数据类型
  • C#实现数组元素的数据类型转换方法详解
    目录一、场景假设二、解决方案三、问题延伸四、数组类的静态转换方法五、刨根问底一、场景假设 假设有一串字符串如下所示,字符串中的数字之间已用英文状态下的逗号隔开。要求用此字符串中的数字...
    99+
    2022-11-13
  • Java中的BaseTypeHandler自定义类型转换器的使用
    目录简述通用的类型转换器(存在一些问题)定制类型转换器简述 mysq5.7之后新增了json类型,但是在使用的过程中,Json数组中的值小于Integer.MAX_VALUE,则反序...
    99+
    2022-11-13
  • Java数据类型转换的示例详解
    目录自动转换转换原理转换规则强制转换注意ASCII编码表Java程序中要求参与的计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生类型的转换。 自动转换 一个int 类...
    99+
    2022-11-13
  • Golang拾遗之自定义类型和方法集详解
    golang拾遗主要是用来记录一些遗忘了的、平时从没注意过的golang相关知识。 很久没更新了,我们先以一个谜题开头练练手: package main import ( ...
    99+
    2023-02-20
    Golang自定义类型 方法集 Golang自定义类型 Golang 方法集
  • Java中的BaseTypeHandler自定义类型转换器如何使用
    这篇文章主要介绍“Java中的BaseTypeHandler自定义类型转换器如何使用”,在日常操作中,相信很多人在Java中的BaseTypeHandler自定义类型转换器如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
    99+
    2023-06-30
  • mybatis自定义参数类型转换器数据库字段加密脱敏
    目录1 问题背景2 解决方案2.1 使用数据库加密算法2.2 使用mybatis的自定义参数类型转换器3 一般web项目使用3.1 创建自定义Java类型3.2 自定义类的转换处理器...
    99+
    2022-11-13
  • TypeScript中定义变量方式以及数据类型详解
    目录TypeScript定义变量变量声明格式变量类型推导JS和TS的数据类型TS中使用JS的数据类型number类型boolean类型string类型Array类型Object类型S...
    99+
    2022-11-13
  • C++中图片类型的识别与转换详解方法
    目录1、图片类型的识别1.1、bmp图片1.2、jpg图片1.3、jpg图片1.4、gif图片1.5、tiff图片1.6、使用CreateFile和ReadFile API函数读取内...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作