简体   繁体   English

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

[英]How can I use different Jackson JsonSerializers for the same Java enum in different places?

In a JEE application, I created an enumeration with some custom label strings for the GUI: 在JEE应用程序中,我为GUI创建了一些自定义标签字符串的枚举:

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

    private String label;

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

Objects with attributes of this enum type get delivered over a REST API. 具有此枚举类型的属性的对象通过REST API传递。 The attribute values get serialized as string IDs, wich is what I need: 属性值被序列化为字符串ID,这是我所需要的:

Class with enum attribute: 具有enum属性的类:

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

Service class: 服务等级:

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 call result: REST调用结果:

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

Great! 大! Now, however, I'd like to also deliver a complete list of IDs and labels through a different REST service class: 但是,现在,我还想通过不同的REST服务类提供ID和标签的完整列表:

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

Desired REST call result: 所需的REST调用结果:

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

I created a custom Jackson JsonSerializer to serialize the enum values as id-label pairs: 我创建了一个定制的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
    {
    ...
    }
}

But now, I cannot find a sensible place to attach this JsonSerializer through an @JsonSerialize annotation. 但是现在,我找不到通过@JsonSerialize批注附加此JsonSerializer的明智位置。 If I attach it to the enum like 如果我将它附加到枚举

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

all enum values get serialized as id-label pairs, which is wrong for all REST calls but one. 所有枚举值都被序列化为id-label对,这对所有REST调用都是错误的,只有一个。

If I attach it to the method supposed to deliver the list of id-value pairs, nothing happens: 如果我将其附加到应该传递ID值对列表的方法上,则不会发生任何事情:

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

REST call result: REST调用结果:

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

I know that I could attach the "id-label serializer" to the enum itself and then attach another serializer that restores the default serialization again to all other occurences of the enum, but is there a smarter way to achieve the desired different serializations in the different spots? 我知道我可以将“ id-label序列化程序”附加到枚举本身,然后附加另一个序列化程序,该序列化程序再次将默认序列化还原到该枚举的所有其他出现,但是有一种更聪明的方法可以在枚举中实现所需的不同序列化不同的地方?

You can specify per-property custom serializers using @JsonSerialize(using=MySerializer.class) . 您可以使用@JsonSerialize(using=MySerializer.class)指定每个属性的自定义序列化@JsonSerialize(using=MySerializer.class)

In case of List s and arrays, you will need to use: 如果使用List和数组,则需要使用:

@JsonSerialize(contentsUsing=MySerializer.class)

since using would replace serializer used for List or array itself; 因为using将替换用于List或数组本身的序列化器; for values a different serializer is used. 对于值,使用不同的串行器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM