Springboot自定义出入参格式序列化

springboot自定义出入参格式序列化

场景:由于某种特殊原因,java侧需要对输入的double类型的经纬度转为D-M-S的格式,在对象出参的时候又需要将D-M-S转为小数类型。

DMS转换工具类

public class DmsToDecimalConverter {

    // 正则表达式用于解析DMS格式的字符串
    private static final String REGEX_DMS = "([0-9]+)°([0-9]+)′([0-9.]+)″";


    /**
     * Validates whether the given string is in correct DMS format for latitude or longitude.
     *
     * @param dmsString The string to validate.
     * @return true if the string matches the DMS format, false otherwise.
     */
    public static boolean isValidDms(String dmsString) {
        Pattern pattern = Pattern.compile(REGEX_DMS);
        Matcher matcher = pattern.matcher(dmsString.trim());
        return matcher.matches();
    }

    /**
     * 将DMS格式的经纬度转换为十进制度(DD)。
     * 
     * @param dms DMS格式的经纬度字符串,例如:"120°18′20″"
     * @return 十进制度(DD)的值
     */
    public static double dmsToDecimal(String dms) {
        if (dms == null || dms.isEmpty()) {
            throw new IllegalArgumentException("DMS string cannot be null or empty.");
        }

        String[] parts = dms.split("°|′|″");
        if (parts.length != 3) {
            throw new IllegalArgumentException("Invalid DMS format: " + dms);
        }

        double degrees = Double.parseDouble(parts[0]);
        double minutes = Double.parseDouble(parts[1]);
        double seconds = Double.parseDouble(parts[2]);

        return degrees + minutes / 60 + seconds / 3600;
    }

    /**
     * 将十进制度(DD)的经纬度转换为DMS格式的字符串。
     * 
     * @param decimal 十进制度(DD)的值
     * @return DMS格式的经纬度字符串
     */
    public static String decimalToDms(double decimal) {
        long deg = (long) decimal;
        double minSec = (decimal - deg) * 60;
        long min = (long) minSec;
        double sec = (minSec - min) * 60;

        DecimalFormat df = new DecimalFormat("#.00");
        return deg + "°" + min + "′" + (int) sec + "″";
    }
}

入参转换

创建自定义反序列化类

创建一个自定义反序列化类LongitudeAndLatitudeDoubleToStringSerialize继承com.fasterxml.jackson.databind.JsonDeserializer

/**
 * @author wuhming
 * @description ""
 * @date 2024/7/31 09:55
 */
public class LongitudeAndLatitudeDoubleToStringSerialize extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonToken jsonToken = jsonParser.currentToken();
        if(jsonToken == JsonToken.VALUE_STRING){
            String value = jsonParser.getValueAsString();
            if(value != null && !DmsToDecimalConverter.isValidDms(value)){
                String decimalToDms = DmsToDecimalConverter.decimalToDms(Double.parseDouble(value.trim()));
                return decimalToDms;
            }
        }
        return jsonParser.getText();
    }
}

com.fasterxml.jackson.core.JsonParser基础方法

  1. 读取基本类型:
    • getText() 读取字符串值。
    • getBooleanValue() 读取布尔值。
    • getIntValue() 读取整数值。
    • getLongValue() 读取长整型值。
    • getDoubleValue() 读取浮点数值。
  2. 读取数组:
    • nextToken() 移动到下一个token,并检查token类型。
    • nextValue() 读取下一个值。
  3. 读取对象:
    • nextToken()nextValue() 也可以用于读取对象的键值对。
  4. 判断当前token类型:
    • currentToken() 返回当前token的类型。
    • hasNext() 判断是否有下一个元素。

使用

在入参实体类字段上面使用

@Data
public class TrackInfo implements Serializable {

    @ApiModelProperty(value = "序列id", hidden = true)
    private Long sequenceId;

    @ApiModelProperty("经度")
    @JsonDeserialize(using = LongitudeAndLatitudeDoubleToStringSerialize.class)
    private String longitude;

    @ApiModelProperty("纬度")
    @JsonDeserialize(using = LongitudeAndLatitudeDoubleToStringSerialize.class)
    private String latitude;

    @ApiModelProperty("时间点")
    private String datePoint;

    @ApiModelProperty("速度")
    private String speed;

    @ApiModelProperty("航向")
    private String heading;

    @ApiModelProperty("高度")
    private String height;
}

出参转换

创建自定义序列化类

创建一个自定义序列化类:LongitudeAndLatitudeToDoubleStringSerialize继承com.fasterxml.jackson.databind.JsonSerializer

/**
 * @author wuhming
 * @description ""
 * @date 2024/7/30 16:13
 */
public class LongitudeAndLatitudeToDoubleStringSerialize extends JsonSerializer<String> {

    @Override
    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if(value != null && DmsToDecimalConverter.isValidDms(value)){
            double dmsToDecimal = DmsToDecimalConverter.dmsToDecimal(value);
            jsonGenerator.writeString(String.valueOf(dmsToDecimal));
        }
    }
}

使用

在出参实体类字段上面使用:

@Data
@AllArgsConstructor
@NoArgsConstructor
public  class Point {

    @ApiModelProperty("经度")
    @JsonSerialize(using = LongitudeAndLatitudeToDoubleStringSerialize.class)
    private String longitude;

    @ApiModelProperty("纬度")
    @JsonSerialize(using = LongitudeAndLatitudeToDoubleStringSerialize.class)
    private String latitude;

    @ApiModelProperty("时间点")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date datePoint;
}

拓展

https://blog.csdn.net/qq_33204709/article/details/137802136

0%