我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring中字段格式化的使用小结

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring中字段格式化的使用小结

Spring提供的一个core.convert包 是一个通用类型转换系统。它提供了统一的 ConversionService   API和强类型的Converter SPI,用于实现从一种类型到另一种类型的转换逻辑。Spring容器使用这个系统绑定bean属性值。此外,Spring Expression Language (SpEL)和DataBinder都使用这个系统来绑定字段值。例如,当SpEL需要将Short强制转换为Long来完成表达式时。setValue(对象bean,对象值)尝试,核心。转换系统执行强制转换。

现在考虑典型客户端环境(例如web或桌面应用程序)的类型转换需求。在这种环境中,通常从String转换为支持客户端回发过程,并返回String以支持视图呈现过程。此外,你经常需要本地化String值。更一般的core.convert Converter SPI不能直接解决这些格式要求。为了直接解决这些问题,Spring 3引入了一个方便的Formatter SPI,它为客户端环境提供了PropertyEditor实现的一个简单而健壮的替代方案。

通常,当你需要实现通用类型转换逻辑时,你可以使用Converter SPI,例如,用于java.util.Date和Long之间的转换。当你在客户端环境(例如web应用程序)中工作并需要解析和打印本地化的字段值时,你可以使用Formatter SPI。ConversionService为这两个spi提供了统一的类型转换API。

1、Formatter SPI

实现字段格式化逻辑的Formatter SPI是简单且强类型的。下面的清单显示了Formatter接口定义:

package org.springframework.format;
public interface Formatter<T> extends Printer<T>, Parser<T> {
}

Formatter继承自Printer和Parser接口。

@FunctionalInterface
public interface Printer<T> {
  String print(T object, Locale locale);
}
@FunctionalInterface
public interface Parser<T> {
  T parse(String text, Locale locale) throws ParseException;
}

默认情况下Spring容器提供了几个Formatter实现。数字包提供了NumberStyleFormatter、CurrencyStyleFormatter和PercentStyleFormatter来格式化使用java.text.NumberFormat的number对象。datetime包提供了一个DateFormatter来用java.text.DateFormat格式化 java.util.Date对象。

自定义Formatter。

public class StringToNumberFormatter implements Formatter<Number> {
  @Override
  public String print(Number object, Locale locale) {
    return "结果是:" + object.toString();
  }
  @Override
  public Number parse(String text, Locale locale) throws ParseException {
    return NumberFormat.getInstance().parse(text);
  }
}

如何使用?我们可以通过FormattingConversionService 转换服务进行添加自定义的格式化类。

FormattingConversionService fcs = new FormattingConversionService();
// 默认如果不添加自定义的格式化类,那么程序运行将会报错
fcs.addFormatterForFieldType(Number.class, new StringToNumberFormatter());
Number number = fcs.convert("100.5", Number.class);
System.out.println(number);

查看源码:

public class FormattingConversionService extends GenericConversionService implements FormatterRegistry, EmbeddedValueResolverAware {
  public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) {
    addConverter(new PrinterConverter(fieldType, formatter, this));
    addConverter(new ParserConverter(fieldType, formatter, this));
  }
  private static class PrinterConverter implements GenericConverter {}
  private static class ParserConverter implements GenericConverter {}
}
public class GenericConversionService implements ConfigurableConversionService {
  private final Converters converters = new Converters();
  public void addConverter(GenericConverter converter) {
    this.converters.add(converter);
  }
}

Formatter最后还是被适配成GenericConverter(类型转换接口)。

2、基于注解的格式化

字段格式化可以通过字段类型或注释进行配置。要将注释绑定到Formatter,请实现AnnotationFormatterFactory。

public interface AnnotationFormatterFactory<A extends Annotation> {
  Set<Class<?>> getFieldTypes();
  Printer<?> getPrinter(A annotation, Class<?> fieldType);
  Parser<?> getParser(A annotation, Class<?> fieldType);
}

类及其方法说明:

参数化A为字段注解类型,你希望将该字段与格式化逻辑关联,例如org.springframework.format.annotation.DateTimeFormat。

  • getFieldTypes()返回可以使用注释的字段类型。
  • getPrinter()返回一个Printer来打印带注释的字段的值。
  • getParser()返回一个Parser来解析带注释字段的clientValue。

自定义注解解析器。

public class StringToDateFormatter implements AnnotationFormatterFactory<DateFormatter> {
  @Override
  public Set<Class<?>> getFieldTypes() {
    return new HashSet<Class<?>>(Arrays.asList(Date.class));
  }
  @Override
  public Printer<?> getPrinter(DateFormatter annotation, Class<?> fieldType) {
    return getFormatter(annotation, fieldType);
  }
  @Override
  public Parser<?> getParser(DateFormatter annotation, Class<?> fieldType) {
    return getFormatter(annotation, fieldType);
  }
  private StringFormatter getFormatter(DateFormatter annotation, Class<?> fieldType) {
    String pattern = annotation.value();
    return new StringFormatter(pattern);
  }
  class StringFormatter implements Formatter<Date> {
    private String pattern;
    public StringFormatter(String pattern) {
      this.pattern = pattern;
    }
    @Override
    public String print(Date date, Locale locale) {
      return DateTimeFormatter.ofPattern(pattern, locale).format(date.toInstant());
    }
    @Override
    public Date parse(String text, Locale locale) throws ParseException {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale);
      return Date.from(LocalDate.parse(text, formatter).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }
  }
}

注册及使用:

public class Main {
  @DateFormatter("yyyy年MM月dd日")
  private Date date;
  public static void main(String[] args) throws Exception {
    FormattingConversionService fcs = new FormattingConversionService();
    fcs.addFormatterForFieldAnnotation(new StringToDateFormatter());
    Main main = new Main();
    Field field = main.getClass().getDeclaredField("date");
    TypeDescriptor targetType = new TypeDescriptor(field);
    Object result = fcs.convert("2022年01月21日", targetType);
    System.out.println(result);
    field.setAccessible(true);
    field.set(main, result);
    System.out.println(main.date);
  }
}

3、FormatterRegistry

FormatterRegistry是用于注册格式化程序和转换器的SPI。FormattingConversionService是FormatterRegistry的一个实现,适用于大多数环境。可以通过编程或声明的方式将该变体配置为Spring bean,例如使用FormattingConversionServiceFactoryBean。因为这个实现还实现了ConversionService,所以您可以直接配置它,以便与Spring的DataBinder和Spring表达式语言(SpEL)一起使用。

public interface FormatterRegistry extends ConverterRegistry {
  void addPrinter(Printer<?> printer);
  void addParser(Parser<?> parser);
  void addFormatter(Formatter<?> formatter);
  void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);
  void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser);
  void addFormatterForFieldAnnotation(AnnotationFormatterFactory<? extends Annotation> annotationFormatterFactory);
}

4、SpringMVC中配置类型转换

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
  @Override
  public void addFormatters(FormatterRegistry registry) {
    // ...
  }
}

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;
    }    
  }
}

到此这篇关于Spring中字段格式化的使用详解的文章就介绍到这了,更多相关Spring字段格式化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring中字段格式化的使用小结

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

下载Word文档

猜你喜欢

Python中字符串的格式化方法小结

老办法 Python2.6之前,格式字符串的使用方法相对更简单些,虽然其能够接收的参数数量有限制。这些方法在Python3.3中仍然有效,但已有含蓄的警告称将完全淘汰这些方法,目前还没有明确的时间进度表。 格式化浮点数:pi = 3.141
2022-06-04

Python实现字符串格式化的方法小结

Python2.6+ 增加了str.format函数,用来代替原有的'%'操作符。它使用比'%'更加直观、灵活。下面详细介绍一下它的使用方法。 下面是使用'%'的例子:"" "PI is %f..." % 3.14159 # => 'PI
2022-06-04

python中的格式化输出用法总结

本文实例总结了python中的格式化输出用法。分享给大家供大家参考,具体如下: Python一共有两种格式化输出语法。 一种是类似于C语言printf的方式,称为 Formatting Expression>>> '%s %d-%d' %
2022-06-04

如何使用Python中的字符串格式化技巧

如何使用Python中的字符串格式化技巧在Python编程中,字符串格式化是一种非常重要的技巧。它可以让我们更加灵活地处理字符串,将变量插入到字符串中,或者指定字符串的特定格式。本文将介绍Python中常用的字符串格式化方法,并提供具体的代
2023-10-22

使用golang中的json.MarshalIndent函数将结构体转换为格式化的JSON字符串

使用golang中的json.MarshalIndent函数将结构体转换为格式化的JSON字符串在使用Golang编写程序时,我们经常需要将结构体转换为JSON字符串,在这个过程中,json.MarshalIndent函数可以帮助我们实现格
使用golang中的json.MarshalIndent函数将结构体转换为格式化的JSON字符串
2023-11-18

Spring Security中使用authorizeRequests遇到的问题小结

Spring 是非常流行和成功的 Java 应用开发框架,Spring Security 正是 Spring 家族中的成员,这篇文章主要介绍了Spring Security中使用authorizeRequests遇到的问题,需要的朋友可以参考下
2023-02-03

使用其他“部分”结构中的值覆盖结构字段

php小编西瓜在这里为大家介绍一个有关使用其他“部分”结构中的值覆盖结构字段的方法。在编程中,我们经常需要根据不同的情况来更新结构字段的值。这种情况下,我们可以使用其他结构中的值来覆盖目标结构中的字段。这种方法非常实用,可以提高代码的可读性
使用其他“部分”结构中的值覆盖结构字段
2024-02-12

Python3中怎么使用format函数格式化字符串

Python3中怎么使用format函数格式化字符串,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在Python3中,字符串格式化操作通过format()方法或者f’strin
2023-06-02

PHP中如何使用sprintf()函数格式化字符串

本篇文章给大家分享的是有关PHP中如何使用sprintf()函数格式化字符串,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。语法: string sprintf(string f
2023-06-17

怎么在python中使用f方法格式化字符串

怎么在python中使用f方法格式化字符串?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对
2023-06-14

Goland字符串格式化样式中“\r“的作用详解

这篇文章主要介绍了Goland字符串格式化样式中“\r“的作用,"\r"起的作用是回到行首,当前控制台输出,输出完以后回到当前行的行首,本文给大家介绍的非常详细,需要的朋友可以参考下
2023-05-18

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录