如何在Spring API中修改Duration类型的输出格式?
解决方案:不修改Duration类型实现友好格式序列化
Jackson默认对Duration采用ISO-8601格式(如PT15S)序列化,@JsonFormat的pattern参数对Duration不生效,因此需要通过自定义序列化逻辑来实现友好格式输出,且无需修改实体和DTO的类型。
方法一:给DTO字段单独配置自定义序列化器
步骤1:编写自定义Duration序列化器
根据需求选择以下两种格式的序列化器:
格式1:简洁风格(如15s、5m30s、1h5m30s)
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.time.Duration; public class FriendlyDurationSerializer extends JsonSerializer<Duration> { @Override public void serialize(Duration duration, JsonGenerator gen, SerializerProvider serializers) throws IOException { long hours = duration.toHours(); long minutes = duration.toMinutes() % 60; long seconds = duration.getSeconds() % 60; StringBuilder sb = new StringBuilder(); if (hours > 0) { sb.append(hours).append("h"); } if (minutes > 0 || hours > 0) { sb.append(minutes).append("m"); } if (seconds > 0 || minutes == 0 && hours == 0) { sb.append(seconds).append("s"); } gen.writeString(sb.toString()); } }
格式2:时分秒补零格式(如00:05:30、01:02:30)
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.time.Duration; import java.util.Locale; public class HmsDurationSerializer extends JsonSerializer<Duration> { @Override public void serialize(Duration duration, JsonGenerator gen, SerializerProvider serializers) throws IOException { long hours = duration.toHours(); long minutes = duration.toMinutes() % 60; long seconds = duration.getSeconds() % 60; String formatted = String.format(Locale.ROOT, "%02d:%02d:%02d", hours, minutes, seconds); gen.writeString(formatted); } }
步骤2:在DTO字段上应用序列化器
修改MyCallDto的duration字段,添加@JsonSerialize注解指定自定义序列化器:
public class MyCallDto { private Long id; private Instant date; // 二选一即可 @JsonSerialize(using = FriendlyDurationSerializer.class) // @JsonSerialize(using = HmsDurationSerializer.class) private Duration duration; }
方法二:全局配置Jackson序列化器(所有Duration生效)
如果希望项目中所有Duration类型都使用统一的友好格式,可通过Spring配置全局注册序列化器:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ObjectMapper; import java.time.Duration; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 选择一种序列化器注册 module.addSerializer(Duration.class, new FriendlyDurationSerializer()); // module.addSerializer(Duration.class, new HmsDurationSerializer()); objectMapper.registerModule(module); return objectMapper; } }
注意事项
- 两种方案都不会修改
Duration类型本身,仅在JSON序列化阶段转换输出格式。 - 反序列化逻辑不受影响,前端传入的ISO格式(如
PT15S)依然可以被Jackson正确解析为Duration对象。
内容的提问来源于stack exchange,提问作者Llexii
相关产品推荐
相关产品推荐

