Micronaut HttpResponse中ISO-8601日期格式转换失效问题
Micronaut中日期序列化无法输出
yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式 问题场景
需要将日期以yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式返回(例如2024-05-01T19:52:33.411+00:00),但Micronaut的HttpResponse序列化后实际返回的是2024-05-01T19:52:33.411Z,不符合预期。
现有代码
控制器代码
import com.fasterxml.jackson.core.JsonProcessingException; import io.micronaut.http.*; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.scheduling.TaskExecutors; import io.micronaut.scheduling.annotation.ExecuteOn; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @AllArgsConstructor @Controller @Slf4j @ExecuteOn(TaskExecutors.BLOCKING) public class LogisticsController1 { @Get("/test") public Mono<HttpResponse<Object>> getRes() throws ParseException, JsonProcessingException { String d="2024-05-01T19:52:33.411Z"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); Date date2=simpleDateFormat.parse(d); TestDate date11=new TestDate(); date11.setDate(date2); return Mono.just(buildResponse(date11)); } public HttpResponse<Object> buildResponse(TestDate date11) throws JsonProcessingException { return HttpResponse.status(HttpStatus.OK).body(date11); } }
DTO代码
import io.micronaut.serde.annotation.Serdeable; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.util.Date; @Setter @Getter @NoArgsConstructor @Serdeable public class TestDate { //@JsonFormat( shape = STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date date; }
实际响应 vs 预期响应
- 实际响应:
{ "date": "2024-05-01T19:52:33.411Z" }
- 预期响应:
{ "date": "2024-05-01T19:52:33.411+00:00" }
已尝试的无效方案
添加Jackson的@JsonFormat(shape = STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")注解,该注解对非ISO-8601格式生效,但无法将Z转换为+00:00格式。
解决方案
原因分析
项目使用了Micronaut的micronaut-serde模块(DTO上的@Serdeable注解可证明),而非传统的Jackson jackson-databind。Jackson的@JsonFormat注解对Micronaut Serde不生效,需使用Micronaut Serde自带的注解。
步骤1:使用Micronaut Serde的@JsonFormat注解
修改DTO代码,导入io.micronaut.serde.annotation.JsonFormat包并添加注解:
import io.micronaut.serde.annotation.Serdeable; import io.micronaut.serde.annotation.JsonFormat; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.util.Date; @Setter @Getter @NoArgsConstructor @Serdeable public class TestDate { @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date date; }
步骤2:全局配置(可选)
若需所有日期类型统一使用该格式,可在application.yml中添加全局序列化配置:
micronaut: serde: date-time: format: "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
步骤3:验证效果
重启服务后调用/test接口,将返回预期格式:
{ "date": "2024-05-01T19:52:33.411+00:00" }
内容的提问来源于stack exchange,提问作者deepak singh
相关产品推荐
相关产品推荐

