springboot 注解属性转换字典

1.注解相关功能实现

  1. 定义属性注解

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.vehicle.manager.core.serializer.DicSerializer;


import java.lang.annotation.*;

/**
 * @author zr 2024/2/28
 */
@JacksonAnnotationsInside
@JsonSerialize(
        using = DicSerializer.class
)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Dic {
    String code();
    String fieldName()default "";
}
  1. 定义字典序列化器

import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.vehicle.manager.core.annotation.Dic;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Objects;

/**
 * @author zr 2024/2/28
 */

public class DicSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private String code;
    private String fieldName;


    public DicSerializer(String code, String fieldName) {
        this.code = code;
        this.fieldName = fieldName;
    }

    public DicSerializer() {
    }

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(s);
        jsonGenerator.writeFieldName(fieldName);
        //这一步是通过code(字典类型code)和value(字段转换前的值)获取name(字段转换后的值),
        String name = DicData.getNameByCodeAndValue(this.code,s);
        jsonGenerator.writeString(name);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if(beanProperty !=null){
            if(Objects.equals (beanProperty.getType ().getRawClass (), String.class)){
                Dic t =beanProperty.getAnnotation (Dic.class);
                if(t !=null){
                    String beanFieldName = beanProperty.getName();
                    if(StringUtils.hasText(t.fieldName())){
                        beanFieldName = t.fieldName();
                    }
                    return new DicSerializer(t.code(),beanFieldName+"Text");
                }
            }
            return serializerProvider.findValueSerializer (beanProperty.getType (), beanProperty);
        }
        return serializerProvider.findNullValueSerializer (beanProperty);
    }
}
  1. 虚假的字典数据类


import java.util.HashMap;
import java.util.Map;

/**
 * 字典数据
 */
public class DicData {

    public static final Map<String, Map<Object,String>> dicData = new HashMap<>();
    static {
        //        todo 目前写死,可存入数据库或缓存
        //        车辆状态
        Map<Object,String> m1 = new HashMap();
        m1.put("0","初始化");
        dicData.put("carStatus",m1);
    }


    public static String  getNameByCodeAndValue(String code,String value){
        return dicData.get(code).get(value);
    }

}

2.功能测试

测试场景:

  1. 使用mybatis plus查询数据库car表,将数据封装到CarDO(Car)
  2. 在service层将CarDO转换为CarVo,同时将CarDO的status字段通过注解转换并生成一个新的字段statusText
  1. CarDO
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;

import java.time.LocalDate;

import com.baomidou.mybatisplus.annotation.TableId;

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.vehicle.manager.core.annotation.Dic;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * <p>
 * 车辆信息
 * </p>
 *
 * @author MybatisGenerator
 * @since 2024-02-21
 */
@TableName("car")
@ApiModel("车辆实体类")
@Data
//@Accessors(chain = true)
public class Car extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 2781951723978392659L;

    /**
     * 自增id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    // *****其他属性省略*****

    /**
     * 车辆状态
     */
    @TableField("status")
    private String status;
}

  1. CarVo

此处Vo属性上加上自定义注解@Dic

import com.fasterxml.jackson.annotation.JsonFormat;
import com.vehicle.manager.core.annotation.Dic;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDate;

/**
 * <p>
 * 车辆信息
 * </p>
 *
 * @author MybatisGenerator
 * @since 2024-02-21
 */
@ApiModel("车辆实体类")
@Data
@Accessors(chain = true)
public class CarVo extends BaseVo implements Serializable {
    private static final long serialVersionUID = 2781951723978392659L;

    /**
     * 自增id
     */
    @ApiModelProperty("自增id")
    private Long id;

   // *****其他属性省略*****

    /**
     * 车辆状态
     */
    @ApiModelProperty("车辆状态")
    @Dic(code = "carStatus")
    private String status;

}

  1. 相关service实现类(service接口我就不写了)
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vehicle.manager.core.mapper.CarMapper;
import com.vehicle.manager.core.model.Result;
import com.vehicle.manager.core.model.dto.CarQueryDto;
import com.vehicle.manager.core.model.entity.Car;
import com.vehicle.manager.core.model.enumeration.CommonResultStatus;
import com.vehicle.manager.core.model.vo.CarVo;
import com.vehicle.manager.core.service.CarService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author zr 2024/2/26
 */
@Service
public class CarServiceImpl implements CarService {
    @Autowired
    private CarMapper carMapper;
    
    @Override
    public Result page(CarQueryDto carQueryDto) {
        Page<Car> rowPage = new Page(carQueryDto.getPageNum(),carQueryDto.getPageSize());
        LambdaQueryWrapper<Car> queryWrapper = new LambdaQueryWrapper<>();
        Page<Car> carPage = carMapper.selectPage(rowPage, queryWrapper);
        IPage<CarVo> carVoIPage = carPage.convert(res -> getCarVo(res));
        return Result.success(carVoIPage);
    }
    
    /**
     * carDo 转 carVo
     * @param res
     * @return
     */
    private static CarVo getCarVo(Car res) {
        CarVo carVo = new CarVo();
        BeanUtils.copyProperties(res, carVo);
        return carVo;
    }
    /**
     * 通过id查询数据,并封装到carDo中
     */
    @Override
    public Result getById(Integer carId) {
        Car car = carMapper.selectById(carId);
        CarVo carVo = getCarVo(car);
        return Result.success(carVo);
    }

}

  1. 在48行打上断点debug

image.png

  1. 返回给前端的vo数据

可以看到通过注解生成了一个statusText字段,并且为字段中配置的转换后的值

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/416351.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++学习记录 deque容器—数据存取

函数原型&#xff1a; at(int idx); //返回索引idx所指的数据operator[]; //返回索引idx所指的数据front(); //返回容器中第一个数据元素back(); //返回容器中最后一个数据元素 #include<iostream> using nam…

websocket在django中的运用

14-2 聊天室实现思路&#xff1a;轮训、长轮训、websocket_哔哩哔哩_bilibili 参考大佬的B站学习笔记 https://www.cnblogs.com/wupeiqi/p/6558766.html 参考博客 https://www.cnblogs.com/wupeiqi/articles/9593858.html 参考博客 http协议: 是短连接&#xff0c;无状态…

【LeetCode】每日一题:使二叉树所有路径值相等的最小代价

该题采用自底向上的思路的话&#xff0c;很容易想到使用贪心的思想&#xff0c;但是如何进行具体操作却有些难度。 这里补充一个重要的结论&#xff1a;二叉树的数组形式中&#xff0c;第i个节点的父节点是i/2&#xff1b;接下来只需要让自底向上让每个路径上的代价保持最低限…

Python实现自动检测设备连通性并发送告警到企业微信

背景&#xff1a;门禁机器使用的WiFi连接&#xff0c;因为某些原因会不定期自动断开连接&#xff0c;需要人工及时干预&#xff0c;以免影响门禁数据同步&#xff0c;故写此脚本&#xff0c;定时检测门禁网络联通性。 #首次使用要安装tcping模块 pip install tcpingfrom tcpin…

Jupyter Notebook 下载+简单设置

这里写目录标题 1. Jupyter Notebook安装2.切换打开别的盘3. 创建代码文件4.为jupyter notebook添加目录 (Jupyter安装拓展nbextensions)step1&#xff1a;安装命令step2&#xff1a;用户配置step3&#xff1a;上述过程均完成后&#xff0c;打开jupyter notebook就会发现界面多…

静态方式部署集中式网关

在静态方式部署集中式网关的场景中&#xff0c;控制平面的流程包括VXLAN隧道建立、MAC地址动态学习&#xff1b;转发平面的流程包括同子网已知单播报文转发、同子网BUM&#xff08;Broadcast&Unknown-unicast&Multicast&#xff09;报文转发、跨子网报文转发。 静态方…

qml 项目依赖

文章目录 出现的问题最终对比下一步 把 apptestQml3_6.exe 放到一个单独目录下&#xff0c;执行 windeployqt.exe ./apptestQml3_6.exe但是出了很多问题&#xff0c;根本运行不起来。 但是在release目录下执行下&#xff0c;程序能跑起来。 根据错误提示&#xff0c;进行添加。…

vue3+vite+ts配置多个代理并解决报404问题

之前配置接口代理总是报404,明明接口地址是对的但还是报是因数写法不对;用了vue2中的写法 pathRewrite改为rewrite 根路径下创建env文件根据自己需要名命 .env.development文件内容 # just a flag ENVdevelopment# static前缀 VITE_APP_PUBLIC_PREFIX"" # 基础模块…

php 支持mssqlserver

系统不支持:sqlsrv 需要一下几个环节 1.准备检测php版本 查看 VC 版本 查看操作系统位数&#xff1a;X86(32位) 和X64 2.下载php的sqlserver库 extensionphp_sqlsrv_74_nts_x64.dll extensionphp_pdo_sqlsrv_74_nts_x64.dll extensionphp_sqlsrv_74_nts_x64 extensionphp_…

基于Vue的高校课程考勤成绩管理系统SpringBoot+nodejs+python

设计目标&#xff1a; 课程管理系统开发的目的是管理全校开设课程的基本信息&#xff0c;安排各班级的课程以及上课时间和教室。系统的使用对象包括教务,学生、教师、管理员等。通过对日常课程管理工作的分析&#xff0c;可以将课程管理系统的功能分为下面几个方面&#xff1a…

C++ //练习10.3 用accumulate求一个vector<int>中的元素之和。

C Primer&#xff08;第5版&#xff09; 练习 10.3 练习10.3 用accumulate求一个vector中的元素之和。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*******************************************************************…

DataGrip2023配置连接Mssqlserver、Mysql、Oracle若干问题解决方案

1、Mssqlserver连接 本人连的是Sql2008&#xff0c;默认添加时&#xff0c;地址、端口、实例、账号、密码后&#xff0c;测试连接出现错误。 Use SSL&#xff1a;不要勾选 VM option&#xff1a;填写&#xff0c;"-Djdk.tls.disabledAlgorithmsSSLv3, RC4, DES, MD5withR…

(Linux学习二)文件管理基础操作命令笔记

Linux目录结构&#xff1a; bin 二进制文件 boot 启动目录 home 普通用户 root 超管 tmp 临时文件 run 临时运行数据 var 日志 usr 应用程序、文件 etc 配置文件 dev 文件系统 一、基础操作 在 Linux 终端中&#xff0c;你可以使用以下命令来清屏&#xff1a; clear 命令&am…

HW高水位问题及解决办法

一、问题描述及分析 应用业务反馈应用响应缓慢。登录数据库检查&#xff0c;发现数据库响应慢&#xff0c;有大量enq:HW–contention等待事件。结合awr报告和ash报告&#xff0c;发现整体等待时间消耗在推高水位线征用上&#xff0c;如下awr top事件&#xff1a;Ash消耗也是en…

数据恢复软件有哪些?分享10款好用的数据恢复软件

在数字化时代&#xff0c;数据的安全性和可恢复性变得至关重要。由于各种原因&#xff0c;如设备故障、误删、病毒攻击等&#xff0c;我们可能会面临数据丢失的风险。为了应对这种情况&#xff0c;市场上涌现出许多数据恢复软件。下面给大家分享10个好用的数据恢复软件&#xf…

[golang] 25 图片操作

用 “github.com/fogleman/gg” 可以画线, 框 用 “github.com/disintegration/imaging” 可以变换颜色 一 渲染 1.1 框和字 import "github.com/fogleman/gg"func DrawRectangles(inPath string, cRects []ColorTextRect, fnImgNameChange FnImgNameChange) (str…

C语言数据结构基础-单链表

1.链表概念 在前面的学习中&#xff0c;我们知道了线性表&#xff0c;其中逻辑结构与物理结构都连续的叫顺序表&#xff0c;那么&#xff1a; 链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 2.链表组…

线性稳压器电路,用于各种电视机、收录机、电子仪器、设备的稳压电源上,内置短路保护电路,热保护电路——78MXX

78MXX系列是用于各种电视机、收录机、电子仪器、设备的稳压电源电路。包括78M05、78M06、 78M08、 78M09、 78M10、 78M12、 78M15。 主要特点&#xff1a; ● 极限输出电流: 0.5A ● 固定输出电压: 5V、6V、8V、9V、10V、 12V、 15V ● 内置短路保护电路 ● 内置热保护电路 …

云原生精品资料合集(附下载)

云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声&#xff0c;以应用价值为中心的云原生时代已经到&#xff0c;所以IT人员学习云原生正当时&#xff01;最近跟各位大神征集了云原生的教程&#xff0c;行业报告和最佳实践&#xff0c;总有一款适…

python web框架fastapi模板渲染--Jinja2使用技巧总结

文章目录 1.jinja2模板1.1、jinja2 的变量1.1.1 列表类型数据渲染1.1.2 字典类型数据渲染 2. jinja2 的过滤器3. jinja2 的控制结构3.1、分支控制3.2、循环控制 1.jinja2模板 要了解jinja2&#xff0c;那么需要先理解模板的概念。模板在Python的web开发中⼴泛使⽤&#xff0c;…