首页 > 其他分享 >前后端 int类型和枚举的转换

前后端 int类型和枚举的转换

时间:2024-06-18 14:57:08浏览次数:10  
标签:code 转换 ItemType int name 枚举 public String

查询标签列表

LabelController中增加如下内容

@Operation(summary = "(根据类型)查询标签列表")
@GetMapping("list")
public Result<List<LabelInfo>> labelList(@RequestParam(required = false) ItemType type) {

    LambdaQueryWrapper<LabelInfo> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(type != null, LabelInfo::getType, type);
    List<LabelInfo> list = service.list(queryWrapper);
    return Result.ok(list);
}

知识点

上述接口的功能是根据type(公寓/房间),查询标签列表。由于这个type字段在数据库、实体类、前后端交互的过程中有多种不同的形式,因此在请求和响应的过程中,type字段会涉及到多次类型转换。

首先明确一下type字段的各种形式:

  • 数据库中

    数据库中的type字段为tinyint类型

    +-------------+--------------+
    | Field       | Type         |
    +-------------+--------------+
    | id          | bigint       |
    | type        | tinyint      |
    | name        | varchar(255) |
    | create_time | timestamp    |
    | update_time | timestamp    |
    | is_deleted  | tinyint      |
    +-------------+--------------+
    
  • 实体类

    实体类中的type字段为ItemType枚举类型

    LabelInfo实体类如下

    @Schema(description = "标签信息表")
    @TableName(value = "label_info")
    @Data
    public class LabelInfo extends BaseEntity {
    
        private static final long serialVersionUID = 1L;
    
        @Schema(description = "类型")
        @TableField(value = "type")
        private ItemType type;
    
        @Schema(description = "标签名称")
        @TableField(value = "name")
        private String name;
    }
    

    ItemType枚举类如下

    public enum ItemType {
    
        APARTMENT(1, "公寓"),
        ROOM(2, "房间");
    
        private Integer code;
        private String name;
    
        ItemType(Integer code, String name) {
            this.code = code;
            this.name = name;
        }
    }
    
  • 前后端交互中

    前后端交互所传递的数据中type字段为数字(1/2)。

image

具体转换过程如下图所示:

  • 请求流程
    image

    说明

    • SpringMVC中的WebDataBinder组件负责将HTTP的请求参数绑定到Controller方法的参数,并实现参数类型的转换。
    • Mybatis中的TypeHandler用于处理Java中的实体对象与数据库之间的数据类型转换。
  • 响应流程
    image

    说明

    • SpringMVC中的HTTPMessageConverter组件负责将Controller方法的返回值(Java对象)转换为HTTP响应体中的JSON字符串,或者将请求体中的JSON字符串转换为Controller方法中的参数(Java对象),例如下一个接口保存或更新标签信息
      image

下面介绍一下每个环节的类型转换原理

  • WebDataBinder枚举类型转换

    WebDataBinder依赖于Converter实现类型转换,若Controller方法声明的@RequestParam参数的类型不是StringWebDataBinder就会自动进行数据类型转换。SpringMVC提供了常用类型的转换器,例如StringIntegerStringDateStringBoolean等等,其中也包括String到枚举类型,但是String到枚举类型的默认转换规则是根据实例名称("APARTMENT")转换为枚举对象实例(ItemType.APARTMENT)。若想实现code属性到枚举对象实例的转换,需要自定义Converter,代码如下,具体内容可参考官方文档

    • web-admin模块自定义com.atguigu.lease.web.admin.custom.converter.StringToItemTypeConverter

      @Component
      public class StringToItemTypeConverter implements Converter<String, ItemType> {
          @Override
          public ItemType convert(String code) {
      
              for (ItemType value : ItemType.values()) {
                  if (value.getCode().equals(Integer.valueOf(code))) {
                      return value;
                  }
              }
              throw new IllegalArgumentException("code非法");
          }
      }
      
    • 注册上述的StringToItemTypeConverter,在web-admin模块创建com.atguigu.lease.web.admin.custom.config.WebMvcConfiguration,内容如下:

      @Configuration
      public class WebMvcConfiguration implements WebMvcConfigurer {
      
          @Autowired
          private StringToItemTypeConverter stringToItemTypeConverter;
      
          @Override
          public void addFormatters(FormatterRegistry registry) {
              registry.addConverter(this.stringToItemTypeConverter);
          }
      }
      

    但是我们有很多的枚举类型都需要考虑类型转换这个问题,按照上述思路,我们需要为每个枚举类型都定义一个Converter,并且每个Converter的转换逻辑都完全相同,针对这种情况,我们使用ConverterFactory接口更为合适,这个接口可以将同一个转换逻辑应用到一个接口的所有实现类,因此我们可以定义一个BaseEnum接口,然后另所有的枚举类都实现该接口,然后就可以自定义ConverterFactory,集中编写各枚举类的转换逻辑了。具体实现如下:

    • model模块定义com.atguigu.lease.model.enums.BaseEnum接口

      public interface BaseEnum {
          Integer getCode();
          String getName();
      }
      
    • 令所有com.atguigu.lease.model.enums包下的枚举类都实现BaseEnun接口

    • web-admin模块自定义com.atguigu.lease.web.admin.custom.converter.StringToBaseEnumConverterFactory

      @Component
      public class StringToBaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> {
          @Override
          public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) {
              return new Converter<String, T>() {
                  @Override
                  public T convert(String source) {
      
                      for (T enumConstant : targetType.getEnumConstants()) {
                          if (enumConstant.getCode().equals(Integer.valueOf(source))) {
                              return enumConstant;
                          }
                      }
                      throw new IllegalArgumentException("非法的枚举值:" + source);
                  }
              };
          }
      }
      
    • 注册上述的ConverterFactory,在web-admin模块创建com.atguigu.lease.web.admin.custom.config.WebMvcConfiguration,内容如下:

      @Configuration
      public class WebMvcConfiguration implements WebMvcConfigurer {
      
          @Autowired
          private StringToBaseEnumConverterFactory stringToBaseEnumConverterFactory;
      
          @Override
          public void addFormatters(FormatterRegistry registry) {
              registry.addConverterFactory(this.stringToBaseEnumConverterFactory);
          }
      }
      

      注意:

      最终采用的是ConverterFactory方案,因此StringToItemTypeConverter相关代码可以直接删除。

  • TypeHandler枚举类型转换

    Mybatis预置的TypeHandler可以处理常用的数据类型转换,例如StringIntegerDate等等,其中也包含枚举类型,但是枚举类型的默认转换规则是枚举对象实例(ItemType.APARTMENT)和实例名称("APARTMENT")相互映射。若想实现code属性到枚举对象实例的相互映射,需要自定义TypeHandler

    不过MybatisPlus提供了一个通用的处理枚举类型的TypeHandler。其使用十分简单,只需在ItemType枚举类的code属性上增加一个注解@EnumValue,Mybatis-Plus便可完成从ItemType对象到code属性之间的相互映射,具体配置如下。

    public enum ItemType {
    
        APARTMENT(1, "公寓"),
        ROOM(2, "房间");
    
        @EnumValue
        private Integer code;
        private String name;
    
        ItemType(Integer code, String name) {
            this.code = code;
            this.name = name;
        }
    }
    
  • HTTPMessageConverter枚举类型转换

    HttpMessageConverter依赖于Json序列化框架(默认使用Jackson)。其对枚举类型的默认处理规则也是枚举对象实例(ItemType.APARTMENT)和实例名称("APARTMENT")相互映射。不过其提供了一个注解@JsonValue,同样只需在ItemType枚举类的code属性上增加一个注解@JsonValue,Jackson便可完成从ItemType对象到code属性之间的互相映射。具体配置如下,详细信息可参考Jackson官方文档

    @Getter
    public enum ItemType {
    
        APARTMENT(1, "公寓"),
        ROOM(2, "房间");
    
        @EnumValue
          @JsonValue
        private Integer code;
        private String name;
    
        ItemType(Integer code, String name) {
            this.code = code;
            this.name = name;
        }
    }
    

标签:code,转换,ItemType,int,name,枚举,public,String
From: https://www.cnblogs.com/r1-12king/p/18254350

相关文章

  • 如何将webp格式转换成jpg格式?
    图片格式除了最常见的jpg和png外,还有很多不太经常使用到的格式,webp就是这样一种,它在某些旧版的操作系统、浏览器和图像处理软件中可能不被完全支持。通过将WebP格式转换为JPG格式,可以增加图片在不同平台和设备上的兼容性,确保图片能够正常显示和使用。那么,如何将WebP转JPG呢?接着往......
  • __int1024!
    使用说明:数据范围约为\(-2^{1024}\leN\le2^{1024}\),反映到十进制约为\(-10^{309}\leN\le10^{309}\),但不保证完全如此。输入输出使用自带的输入及输出函数。由于其内部用scanf和printf来实现,所以请不要把它与ios::sync_with_stdio(false)同时使用。由于内部采用高精度实现,......
  • MultiPoint.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个MultiPoint.dll文件(挑选合适的版本文件)把......
  • 【JavaWeb】基于Filter和Interceptor实现登录认证
    前言HTTP协议是无状态协议,指的是每一次请求都是独立的,下一次请求并不会携带上一次请求的数据。因为HTTP协议是无状态的,两次请求之间是独立的,所以是无法判断这个员工到底登陆了没有。登录校验的具体的实现思路可以分为两部分:在员工登录成功后,需要将用户登录成功的信息存起来,记......
  • 每日一题——Python实现PAT甲级1132 Cut Integer(举一反三+思想解读+逐步优化)五千字好
    一个认为一切根源都是“自己不够强”的INTJ个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数Python-3.12.0文档解读目录 我的写法正确性和功能性时间复杂度空间复杂度其他点评总结我要更强优化后的时间复杂度和空间复杂度进一......
  • 深入解析:如何通过Python脚本将YOLO标注格式转换为COCO格式并进行验证
    深入解析:如何通过Python脚本将YOLO标注格式转换为COCO格式并进行验证随着深度学习和计算机视觉技术的飞速发展,物体检测成为了一个热门的研究领域。在物体检测任务中,YOLO(YouOnlyLookOnce)和COCO(CommonObjectsinContext)是两个非常重要的标注格式。YOLO因其高效的实时物......
  • 深入解析:如何通过Python脚本将LabelMe标注格式转换为YOLO格式并进行验证
    深入解析:如何通过Python脚本将LabelMe标注格式转换为YOLO格式并进行验证在计算机视觉领域,标注格式的转换是一个经常会遇到的问题。不同的标注格式有不同的应用场景和优势,能够灵活地进行转换是非常重要的技能。在这篇文章中,我们将详细介绍如何通过Python脚本将LabelMe标注格......
  • OGG Extract / Replicat Checkpoint RBA Is Larger than Local Trail Size (Doc ID 11
    环境:OS:Centos6DB:11.2.0.4ogg:12.3.0.1说明:从库突然宕机重启后导致1.报错如下 计算公式:Newdatapump/ReplicatRBA=Reader'stoo-bigcheckpointRBA(A)+FirstrecordRBAinthenewtrailfile(aftertherestartabend)(B)-RBAofthematchingrecord......
  • (slam工具)3 GNSS-ECEF-ENU 坐标系下转换
      https://github.com/Dongvdong/v1_1_slam_tool '''gnss和enu坐标系相互转化'''importnumpyasnpfrompyprojimportProj,TransformerimportpyprojimportmathfromAPI_1GetGpsFromIMGimport*use_cgcs2000Towgs84=0#......
  • 微信小程序开发云环境,使用云函数实现通用印刷体识别, openapi.ocr.printedText
    1.创建新项目时,要选中云开发,APPID不能使用测试号2.微信开发者工具,点击云开发,进行注册使用,刚开始是可以试用30天,之后是需要付费的。3.npminstall--savewx-server-sdk@latest  终端安装此命令https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/img-ocr/ocr/......