必须转换日期、时间和日程表类型的 JSON 绑定

在 JAX-RS 2.1 中,用于在 JSON 和 Java 对象之间序列化与反序列化的内部库已从 Jackson 更改为 Yasson。Yasson 是 JSON-B 的引用实施。Jackson 和 Yasson 采用不同的方式来序列化与时间相关的对象,例如:

Jackson Yasson
java.util.Date 726213720000 1993-02-05T06:02:00Z[UTC]
java.util.Calendar 726213720000 1993-02-05T00:00:00-06:00[America/Chicago]
java.time.Instant { "epochSecond":726213720, "nano":0 } 1993-02-05T06:02:00Z
java.time.LocalDate { "year":1993, "month":"FEBRUARY", "dayOfMonth":5, ... } 1993-02-05

此规则将标记产生或使用以下类型的 JSON 类型数据的 JAX-RS 资源方法:

产生或使用先前列出的任何类型的方法都需要转换。请注意,产生或使用包含任何这些类型的对象的任何方法也需要进行处理。

二进制扫描程序仅检测直接使用或产生先前提到的类型的方法。然而,如果某方法使用或产生包含这些类型的对象,那么二进制扫描程序将检测不到类型用法。如果使用二进制扫描程序,请查看指定 JSON 或通配符的所有 @javax.ws.rs.Produces@javax.ws.rs.Consumes 注释,并确保产生或使用包含任一适用类型的对象的任何方法得到转换。

以下是将由此规则标记的 JAX-RS 资源方法的示例:

@Path("/")
@ApplicationScoped
公用类 MyService {

    @GET
    @Path("/get")
    @Produces(MediaType)。APPLICATION_JSON) public Date getDate() {
        //...
    }

    @GET
    @Path("/set")
    @Consumes(MediaType)。APPLICATION_JSON) public void setDate(日期日期) {
        //...
    } }

对于直接返回 java.util.Datejava.util.Calendar 的 JAX-RS 资源方法, 返回类型应更改为类型 long,以保持与 Jackson 相同的输出。例如,如果方法返回 Date 对象,如此处所示:

    @GET
    @Path("/get")
    @Produces(MediaType)。APPLICATION_JSON) public Date getDate() {
        return new Date(...);
    }

那么可按如下方式更改该方法:

    @GET
    @Path("/get")
    @Produces(MediaType)。APPLICATION_JSON) public long getDate() {
        return new Date(...).getTime();
    }

对于 java.time.LocalDate 和 java.time.Instant 类型,调整使用日期的代码变得更简单, 因此可以处理 JSON-B/Yasson 格式。

有关 Jackson 和 Yasson 之间的行为差异的更多详细信息,请参阅 Is it time for a JSON binding standard? 文章“比较 Jackson 和 JSON-B 行为”。