Spring:自定义Converter实现参数转换

背景

多个后端、前端开发时约定日期类型参数时未能统一,即存在2022-12-21 12:45:00,也存在2022/12/21 12:45:00。导致可以复用的接口,前端传参格式却不一样,前端改动的话,工作量比较大,所以在后端做格式兼容处理。

实现

  1. 项目中只有某些字段需要做兼容处理,新建一个注解,用于标识哪些字段需要做兼容处理。

    1
    2
    3
    4
    5
    6
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.PARAMETER})
    @Documented
    public @interface BizDateAdapter {

    }
  2. 实现ConditionalGenericConverter接口,自定义匹配、转换逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @Component
    public class BizDateConverter implements ConditionalGenericConverter {
    //匹配逻辑
    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
    return targetType.hasAnnotation(BizDateAdapter.class);
    }
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
    return null;
    }
    //转换逻辑
    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
    if (source != null && source instanceof String) {
    Date date = DateUtil.parseDate(String.valueOf(source), "yyyy-MM-dd");
    if (date == null){
    date = DateUtil.parseDate(String.valueOf(source), "yyyy/MM/dd");
    }
    return date;
    }
    return source;
    }
    }
  3. 添加自定义的转换器到容器

    1
    2
    3
    4
    5
    6
    7
    8
    @Configuration
    public class IWebMvcConfigurer implements WebMvcConfigurer {
    //......
    @Override
    public void addFormatters(FormatterRegistry registry) {
    registry.addConverter(new BizDateConverter());
    }
    }
  4. 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public ApiResponse xxxxx(
    @RequestParam(value = "userId", required = false) String userId,
    @RequestParam(value = "bizDate") @BizDateAdapter Date bizDate) {
    //......
    }

    @Data
    public class xxxxx {
    @BizDateAdapter
    private Date bizDate;
    //......
    }
请作者喝瓶肥宅快乐水