大数跨境
0
0

SpringBoot优雅定制接口参数格式转换

SpringBoot优雅定制接口参数格式转换 Spring全家桶实战案例
2024-05-28
0
导读:SpringBoot优雅定制接口参数格式转换

环境:SpringBoot3.2.5



1. 简介

在Spring MVC中,数据类型的转换、自动绑定和格式化是一个非常强大的功能,Spring内置了非常多的数据类型转换器。如在一个HTTP请求中SpringMVC默认就具备将JSON个数的数据转换为Java对象,将一个字符串数字转换为Number类型等等。然而,Spring的默认数据绑定机制有时可能无法满足特定的业务需求,比如从特定格式的字符串中解析出自定义对象的实例。为了解决这个问题,Spring允许我们自定义注解和数据格式化器,以便在请求参数和Java对象之间进行自定义的转换。

本篇文章将结合如下需求讲解如何基于SpringBoot环境下自定义注解来实现数据的转换。

现有如下接口

@GetMapping("/user")public User getUser(User user) {  return user ;}

请求url如下:

http://localhost:9001/api/objects/user?user=666,中国

在默认情况下,Spring是无法将这里的user参数值正确的绑定到User对象。

2. 实战案例

2.1 实现目标

为了尽可能的简单,期望通过在接口请求参数上添加一个注解就能完成数据类型的转换及绑定。如下形式:

@GetMapping("/user")public User getUser(@UserFormat User user)

Spring提供了一种基于注解驱动的格式化,也就是上面这里看到的通过注解标注一个参数(字段)来实现数据的格式化。

要实现基于注解驱动的格式化,需要我们自定义类实现AnnotationFormatterFactory接口。该接口定义如下:

// 这里的泛型是注解类型,也就是我们要使用什么注解来标记我们的参数(字段)public interface AnnotationFormatterFactory<A extends Annotation> {  // 这个注解可以使用在什么字段上  Set<Class<?>> getFieldTypes();  // 将对象转换为String  Printer<?> getPrinter(A annotation, Class<?> fieldType);  // 将字符串解析为对象  Parser<?> getParser(A annotation, Class<?> fieldType);}

该接口非常的简单,主要就是如何将对象转String,如何从String转对象。

2.2 自定义注解格式化工厂

public class StringToUserFormatter implements AnnotationFormatterFactory<UserFormat> {    @Override    public Set<Class<?>> getFieldTypes() {      return Set.of(User.class) ;    }    @Override    public Printer<User> getPrinter(UserFormat annotation, Class<?> fieldType) {      return (object, locale) -> object.toString() ;    }    @Override    public Parser<User> getParser(UserFormat annotation, Class<?> fieldType) {      return (text, locale) -> {        Assert.hasText(text, "数据错误") ;        String[] s = text.split(",") ;        User user = new User() ;        user.setId(Long.parseLong(s[0])) ;        user.setName(s[1]) ;        return user ;      } ;    }  }

自定义注解

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public static @interface UserFormat {}

有了以上的工厂类后,接下来是注册到Spring容器中。

2.3 注册格式化器

@Componentpublic class WebDataTypeConfig implements WebMvcConfigurer {  @Override  public void addFormatters(FormatterRegistry registry) {    registry.addFormatterForFieldAnnotation(new StringToUserFormatter()) ;  }}

完成以上步骤就大功告成了,接下来测试

2.4 测试

@GetMapping("/user")public User getUser(@UserFormat User user) {  return user ;}

测试结果

正确的转换为User对象。基于该注解进行格式化不仅仅只用到接口参数上,还可以用到字段上。

2.5 用在字段上

public static class DTO {  @UserFormat  private User user ;  private Integer age ;}

测试接口

// 注意,可不要改成post,然后用@RequestBody。无用反而报错@GetMapping("/dto")public DTO save(DTO dto) {  return dto ;}

测试结果

正确的输出结果。

以上是本篇文章的全部内容,如对你有帮助就请作者吃个棒棒糖🍭。

推荐文章

SpringBoot多租户3种架构实现方案详解

基于SpringBoot通过3种方式轻松搞定敏感字段加密处理

必须掌握SpringBoot强大的自定义属性配置

SpringBoot3.3.0版本发布了!速看都更新了什么?

从SpringBoot2.7开始自动配置发生哪些变化?你都知道吗?

Spring非常强大的2个类知道的人不多

接口响应慢?掌握这优化技巧速度飙升

必须掌握SpringBoot强大的日志功能

Spring注入还可以这样玩!涨知识了

【网关大解密】SpringCloud Gateway 打造极简网关API服务,你一定没用过

掌握API接口优化:高效秘籍,打造极致性能

并发控制实战:乐观锁与Spring AOP重试的完美结合

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读195
粉丝0
内容832