如何在不同的地方为同一个Java枚举使用不同的Jackson JsonSerializer?

时间:2015-04-23 20:25:04

标签: java json enums jackson jsonserializer

在JEE应用程序中,我创建了一个包含GUI的自定义标签字符串的枚举:

public enum MyThing 
{
    THING1("Label 1"),
    ...
    THING5("Label 5");

    private String label;

    private MyThing(String label)
    {
        this.label = label;
    }
    ...
}

具有此枚举类型属性的对象通过REST API传递。属性值被序列化为字符串ID,这就是我需要的:

具有枚举属性的类:

public class MyBO
{
    private MyThing thing;
    ...
}

服务类:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
...

@Path("/bos")
public class MyBOsService
{
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public BO getBO()
    {
        BO bo = new BO();
        ...
        return bo;
    }
}

REST调用结果:

{"thing":"THING1",...}

大!但是,现在,我还希望通过不同的REST服务类提供完整的ID和标签列表:

@Path("/masterdata")
public class MasterDataService
{
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public MyThing[] allMyThings()
    {
        return MyThing.values();
    }
}

所需的REST调用结果:

[{"THING1":"Label 1"},{"THING2":"Label 2"}, ...]

我创建了一个自定义的Jackson JsonSerializer来将枚举值序列化为id-label对:

import org.codehaus.jackson.map.JsonSerializer;
...

public class MyThingSerializer extends JsonSerializer<MyThing>
{
    @Override
    public void serialize(MyThing myThing, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException
    {
    ...
    }
}

但是现在,我找不到通过@JsonSerialize注释附加这个JsonSerializer的合理位置。如果我将它附加到枚举上

@JsonSerialize(using = MyThingSerializer.class)
public enum MyThing{...

所有枚举值都被序列化为id-label对,这对于所有REST调用都是错误的。

如果我将它附加到应该传递id-value对列表的方法上,则没有任何反应:

@Path("/masterdata")
public class MasterDataService
{
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @JsonSerialize(using = MyThingSerializer.class)
    public MyThing[] allMyThings()
    {
        return MyThing.values();
    }
}

REST调用结果:

["THING1","THING2",...]

我知道我可以将“id-label序列化程序”附加到枚举本身,然后附加另一个序列化程序,它将默认序列化再次恢复到枚举的所有其他出现,但有更聪明的方法来实现所需的不同序列化在不同的地方?

1 个答案:

答案 0 :(得分:1)

您可以使用@JsonSerialize(using=MySerializer.class)指定每个属性的自定义序列化程序。

如果是List和数组,则需要使用:

@JsonSerialize(contentsUsing=MySerializer.class)

因为using会替换用于List或数组本身的序列化程序;对于值,使用不同的序列化程序。