You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:32:55