JAX-RS客户端解析响应日期失败问题求助
看起来你遇到的核心问题是两端JSON框架不兼容:Spring Boot用的是Jackson(靠@JsonFormat注解控制日期格式),但JavaEE 7端的JAX-RS客户端默认用的是JSON-B的Yasson实现——Jackson的注解对Yasson完全不起作用,这才导致了日期解析失败。
先拆解下错误根源:Spring Boot输出的日期格式是2016-07-14T21:00:00.000+0000,但Yasson默认的java.util.Date解析规则不匹配这个格式,所以抛出了DateTimeParseException。下面给你几个可行的解决方案:
方案1:在JavaEE端的DTO上使用JSON-B专属注解
既然JavaEE端用的是JSON-B,就把Jackson的@JsonFormat替换成JSON-B的@JsonbDateFormat,并匹配Spring Boot输出的日期格式:
import javax.json.bind.annotation.JsonbDateFormat; import lombok.Data; import java.io.Serializable; import java.util.Date; @Data public class BudgetRecipientsReferenceViewHolder implements Serializable { private static final long serialVersionUID = -2971479083071002129L; private Long treasuryBranchCode; private String budgetRecipientAccount; private String budgetRecipientName; private boolean active; private String budgetRecipientINN; // 完全匹配Spring Boot输出的日期格式 @JsonbDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") private Date openDate; @JsonbDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") private Date closeDate; }
这里的yyyy-MM-dd'T'HH:mm:ss.SSSZ正好对应错误日志里的2016-07-14T21:00:00.000+0000格式,Z用来匹配时区偏移(比如+0000)。
方案2:统一Spring Boot的日期输出格式为Yasson默认支持的类型
如果你不想修改JavaEE端的代码,可以调整Spring Boot的Jackson配置,让它输出Yasson默认能解析的ISO-8601格式日期:
在Spring Boot的application.properties里添加配置:
# 让Jackson输出标准ISO-8601日期格式 spring.jackson.date-format=com.fasterxml.jackson.databind.util.StdDateFormat spring.jackson.serialization.write-dates-as-timestamps=false
或者直接指定格式字符串:
spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss.SSSXXX
这样Spring Boot输出的日期会变成2016-07-14T21:00:00.000Z,Yasson无需额外配置就能正常解析。
方案3:在JavaEE端全局配置Yasson的日期解析规则
如果不想逐个修改DTO的注解,可以在JAX-RS客户端创建时,全局配置Yasson的日期解析格式:
@Override public BudgetRecipientsReferenceViewHolderResponse getBudgetRecipients(String language, DefaultRequest request, String sessionKey) { // 配置Yasson使用指定格式解析日期 JsonbConfig jsonbConfig = new JsonbConfig() .setProperty(JsonbDateFormat.DEFAULT_FORMAT, "yyyy-MM-dd'T'HH:mm:ss.SSSZ") // 可选:开启零时间默认值,作为解析失败的 fallback .setProperty(YassonProperties.ZERO_TIME_PARSE_DEFAULTING, true); Jsonb jsonb = JsonbBuilder.create(jsonbConfig); return ClientBuilder.newClient() .register(new JsonbFeature(jsonb)) // 注册自定义配置的JSON-B处理器 .target(URI.create("http://127.0.0.1:8082/dboreferences/budgetRecipientsReferenceView/getAll")) .request(MediaType.APPLICATION_JSON) .header(GlobalConsts.SESSION_TOKEN, sessionKey) .post(Entity.entity(request, MediaType.APPLICATION_JSON), BudgetRecipientsReferenceViewHolder.class); }
补充小提示
你之前删除@JsonFormat注解没生效,是因为Spring Boot的Jackson默认输出格式和Yasson默认解析格式不匹配;另外注意原注解里的hh是12小时制,而日志里的时间是21点(24小时制),建议统一用HH避免潜在问题。
内容的提问来源于stack exchange,提问作者artyom.poteshkin98




