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
基础方法
- 读取基本类型:
getText()
读取字符串值。getBooleanValue()
读取布尔值。getIntValue()
读取整数值。getLongValue()
读取长整型值。getDoubleValue()
读取浮点数值。
- 读取数组:
nextToken()
移动到下一个token,并检查token类型。nextValue()
读取下一个值。
- 读取对象:
nextToken()
和nextValue()
也可以用于读取对象的键值对。
- 判断当前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;
}