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 "";
}
- 定义字典序列化器
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);
}
}
- 虚假的字典数据类
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.功能测试
测试场景:
- 使用mybatis plus查询数据库car表,将数据封装到CarDO(Car)
- 在service层将CarDO转换为CarVo,同时将CarDO的status字段通过注解转换并生成一个新的字段statusText
- 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;
}
- 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;
}
- 相关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);
}
}
- 在48行打上断点debug
- 返回给前端的vo数据
可以看到通过注解生成了一个statusText字段,并且为字段中配置的转换后的值