切换不同端点的JSON序列化器

时间:2019-02-28 13:45:17

标签: java jackson jersey serializer

Jersey的终结点中,我想返回相同的DTO,但通过使用不同的序列化程序对其进行序列化:需要不同的Date格式。

public class Foo {
    private Date foo;

    public Foo() {
        this.foo = new Date();
    }

    public Date getFoo() {
        return foo;
    }

    public void setFoo(Date foo){
        this.foo = foo;
    }
}

public class MyEndpointsUnix {
    @GET
    @Path("/dateAsUnix")
    public Foo getDateAsUnix() {
        return new Foo();
    }

}

public class MyEndpointsUTC {
    @GET
    @Path("/dateAsUTC")
    public Foo getdateAsUTC() {
        return new Foo();
    }
}

我认为应该可以手动更改序列化器以进行响应。

1 个答案:

答案 0 :(得分:0)

OOP的角度来看,我们可以为每种view创建新的类:

class UnixFoo extends Foo {

    private Foo foo;

    public UnixFoo(Foo foo) {
        this.foo = foo;
    }

    @JsonFormat(pattern = "yyyy-MM-dd")
    @Override
    public Date getFoo() {
        return foo.getFoo();
    }

    // other getters
}

在我们的控制器中,我们可以:

public class MyEndpointsUnix {
    @GET
    @Path("/dateAsUnix")
    public Foo getDateAsUnix() {
        return new UnixFoo(new Foo());
    }
}

当然,此解决方案有一个缺点,我们需要复制我们的DTO类。为了避免这种情况,我们可以使用Jackson MixIn Annotation。为此,我们应该创建新的界面:

interface UnixFooMixIn {

    @JsonFormat(pattern = "yyyy-MM-dd")
    Date getFoo();
}

并使用它来丰富ObjectMapper

public class MyEndpointsUnix {
    @GET
    @Path("/dateAsUnix")
    public String getDateAsUnix() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.addMixIn(Foo.class, UtcFooMixIn.class);

        return mapper.writeValueAsString(new Foo());
    }
}

在这种情况下,我们需要更改方法签名并返回String。同样,我们可以一次创建此ObjectMapper并将其用作单例。对于每种view,我们需要定义新的interface和新的ObjectMapper实例。