Spring Boot 2.x实战44 - Spring Web MVC 16 - Web MVC配置(类型转换原理与设置-AnnotationFormatterFactory)

本文介绍了如何在Spring Boot 2.x中利用`@Format`注解和`AnnotationFormatterFactory`进行参数类型的格式化处理。通过自定义`@CustomDate`和`@CustomMoney`注解,演示了日期和货币格式化的实现。同时,展示了通过配置文件全局设置日期格式。此外,还探讨了如何注册自定义的`Formatter`并应用到控制器验证中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.8.3 AnnotationFormatterFactory

AnnotationFormatterFactory创建Formatter来格式化标记了特殊注解的属性值。

  • NumberFormatAnnotationFormatterFactory使用@NumberFormat注解创建NumberStyleFormatterCurrencyStyleFormatterPercentStyleFormatter这些Formatter来格式化注解的属性。
  • DateTimeFormatAnnotationFormatterFactory使用@DateTimeFormat注解创建DateFormatter的来格式化日期。
3.8.3.1 @DateTimeFormat@NumberFormat

我们演示一下@DateTimeFormat@NumberFormat的使用,定义控制器方法:

@GetMapping("/annoFormatter")
public Map<String, Object> annoFormatter(@DateTimeFormat(pattern = "dd/MM/yyyy")Date date,
                          @DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
                          @NumberFormat(style = NumberFormat.Style.CURRENCY) BigDecimal num,
                          @NumberFormat(style = NumberFormat.Style.PERCENT) BigDecimal num1
                      ){
    Map<String, Object> map = new HashMap<>();
    map.put("date", date);
    map.put("date1", date1);
    map.put("number", num);
    map.put("number1", num1);
    return map;
}

Postman访问地址http://localhost:8080/people/annoFormatter?date=22/04/2019&date1=2019-04-19&num=¥123&num1=39%
在这里插入图片描述
在Spring Boot中可以通过外部配置来全局设置参数中的日期格式:

spring.mvc.date-format: dd/MM/yyyy
3.8.3.2 自定义AnnotationFormatterFactory

同样我们也自定义一个AnnotationFormatterFactory的来作为演示。我们前面已经有了一个PersonFormatter,我们再定义一个Formatter作为条件选择使用:

public class AnotherPersonFormatter implements Formatter<Person> {

    @Override
    public Person parse(String text, Locale locale) throws ParseException {
        String[] personStr = text.split("-");
        Long id = Long.valueOf(personStr[0]);
        String name = personStr[1];
        Integer age = Integer.valueOf(personStr[2]);
        return new Person(id, name, age);
    }

    @Override
    public String print(Person object, Locale locale) {
        return object.toString();
    }
}

定义注解作为选择时候的条件:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PersonFormat {
    boolean style() default true; //根据style选择格式
}

定义PersonFormatAnnotationFormatterFactory实现AnnotationFormatterFactory

        implements AnnotationFormatterFactory<PersonFormat> {
    @Override
    public Set<Class<?>> getFieldTypes() {
        Set<Class<?>> fieldTypes = new HashSet<>(1);
        fieldTypes.add(Person.class);
        return  Collections.unmodifiableSet(fieldTypes); //支持的类型是Person
    }

    @Override
    public Parser<?> getParser(PersonFormat annotation, Class<?> fieldType) {
        if(annotation.style())
            return new PersonFormatter(); //当style为true时使用PersonFormatter格式化
        else
            return new AnotherPersonFormatter(); //为false时使用AnotherPersonFormatter格式化
    }

    @Override
    public Printer<?> getPrinter(PersonFormat annotation, Class<?> fieldType) {
        if(annotation.style())
            return new PersonFormatter();
        else
            return new AnotherPersonFormatter();
    }


}

ConfigurableWebBindingInitializer Bean中定义,通过addFormatterForFieldAnnotation方法添加:

    @Bean
    ConfigurableWebBindingInitializer ConfigurableWebBindingInitializer(FormattingConversionService mvcConversionService){
        ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();

        mvcConversionService.addFormatterForFieldAnnotation(new PersonFormatAnnotationFormatterFactory());
        initializer.setConversionService(mvcConversionService);

        return initializer;

    }

Spring MVC下还可以通过WebMvcConfigurer接口的addFormatter方法注册:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatterForFieldAnnotation(new PersonFormatAnnotationFormatterFactory());
    }
}

使用控制器验证:

@GetMapping("/customAnnoFormatter")
public Map<String, Person> customAnnoFormatter(@PersonFormat @RequestParam Person person,
                                  @PersonFormat(style = false) @RequestParam Person person1){
    Map<String, Person> map = new HashMap<>();
    map.put("person", person);
    map.put("person1", person1);
    return map;
}

在这里插入图片描述

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
在这里插入图片描述

主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值