Java Jackson将字段序列化为不同的名称

Java Jackson将字段序列化为不同的名称,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我要反序列化这个JSON: { "first-name": "Alpha", "last-name": "Beta", "gender": "m" } 我想将其序列化为两种不同的格式: [A] { "first-name": "Alpha", "last-name": "Beta", "gender": "m" } { "firstName": "Alpha", "lastName": "Beta", "gender":

我要反序列化这个JSON:

{
    "first-name": "Alpha",
    "last-name": "Beta",
    "gender": "m"
}
我想将其序列化为两种不同的格式:

[A]

{
    "first-name": "Alpha",
    "last-name": "Beta",
    "gender": "m"
}
{
    "firstName": "Alpha",
    "lastName": "Beta",
    "gender": "m"
}
[B]

{
    "first-name": "Alpha",
    "last-name": "Beta",
    "gender": "m"
}
{
    "firstName": "Alpha",
    "lastName": "Beta",
    "gender": "m"
}
我可以将其序列化为1种格式:[A]或[B]。下面是我将其序列化到[B]的代码:

public String firstName;
public String lastName;
public String gender;

@JsonProperty("firstName")
public String getFirstNameCC() {
    return firstName;
}

@JsonProperty("first-name")
public void setFirstNameD(String firstName) {
    this.firstName = firstName;
}

@JsonProperty("lastName")
public String getLastNameCC() {
    return lastName;
}

@JsonProperty("last-name")
public void setLastNameD(String lastName) {
    this.lastName = lastName;
}

public String getGender() {
    return gender;
}

public void setGender(String gender) {
    this.gender = gender;
}

我在这里读到了
JsonView
(第5节:定制JSON视图),但它只改变了它的值。我想更改字段名,如上例所示。有人能对此给出见解吗?

我不确定我是否完全理解您的问题,但就我所能理解的而言,您可以这样做以实现不同的序列化

创建自定义批注以保存所有可能的不同序列化选项:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomJsonProperty {
    String propertyName();

    String format();

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        CustomJsonProperty[] value();
    }

}
相应地为您的类添加注释:

@JsonSerialize(using = CustomJsonPropertySerializer.class)
public class Bar {

    @CustomJsonProperty.List({
        @CustomJsonProperty(propertyName = "first-name", format = "A"),
        @CustomJsonProperty(propertyName = "firstName", format = "B")
    })
    private String firstName;

    @CustomJsonProperty.List({
            @CustomJsonProperty(propertyName = "last-name", format = "A"),
            @CustomJsonProperty(propertyName = "lastName", format = "B")
    })
    private String lastName;

    @CustomJsonProperty.List({
            @CustomJsonProperty(propertyName = "gender-x", format = "A"),
            @CustomJsonProperty(propertyName = "gender", format = "B")
    })
    private String gender;

    @JsonIgnore
    private String format;

    //getters & setters

}
创建自定义序列化程序以解释新注释:

public class CustomJsonPropertySerializer extends JsonSerializer<Bar> {

    @Override
    public void serialize(Bar bar, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        jsonGenerator.writeStartObject();

        Field[] fields = bar.getClass().getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);
            Object value = null;

            try {
                value = field.get(bar);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            if (field.isAnnotationPresent(CustomJsonProperty.List.class)) {
                CustomJsonProperty[] properties = field.getAnnotation(CustomJsonProperty.List.class).value();
                CustomJsonProperty chosenProperty = null;

                for (CustomJsonProperty c : properties) {
                    if (c.format().equalsIgnoreCase(bar.getFormat())) {
                        chosenProperty = c;
                        break;
                    }
                }

                if (chosenProperty == null) {
                    //invalid format given, use first format then
                    chosenProperty = properties[0];
                }

                jsonGenerator.writeStringField(chosenProperty.propertyName(), value.toString());
            }
        }

        jsonGenerator.writeEndObject();
    }
}
输出:

{"first-name":"first","last-name":"last","gender-x":"m"}
{"firstName":"first","lastName":"last","gender":"m"}
当然,上面的序列化程序只适用于Bar对象,但这可以通过使用继承
抽象字符串getFormat()轻松解决并更改自定义序列化程序以接受超类类型,而不是Bar


也许有一个简单的方法比创造你自己的东西,但我不知道。如果有什么不清楚的地方,请告诉我,我可以再详细说明。

有一种更简单的方法可以做到这一点-创建一个使用“addMixin”函数的objectmapper

要序列化的类:

Class YouWantToSerializeMe {

    public String firstName;
    public String lastName;
    public String gender;

    @JsonProperty("firstName")
    public String getFirstNameCC() {
        return firstName;
    }

    @JsonProperty("lastName")
    public String getLastNameCC() {
    return lastName;
    }
}
现在,要同时使用内置字段名和自定义字段名进行序列化,可以执行以下操作:

Class DoTheSerializing {

    String serializeNormally(YouWantToSerializeMe me) {
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectWriter objectWriter = objectMapper.writer();

         return objectWriter(me)
     }

    String serializeWithMixin(YouWantToSerializeMe me) {
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectWriter objectWriter = objectMapper
                 .addMixIn(YouWantToSerializeMe.class, MyMixin.class)
                 .writer();

         return objectWriter(me)
    }

    interface MyMixin {

         @JsonProperty("first-name")
         public String getFirstNameCC();

         @JsonProperty("last-name")
         public String getLastNameCC();
    }    

}
这在类中使用了一个嵌入式接口来保持事物的局部性。您可以围绕此进行大量优化,例如创建静态ObjectMapper和加载/卸载mixin


使用接口作为“模板”来控制映射功能非常强大。您可以在字段和类级别添加内容

几个星期以来,我一直在寻找解决这个问题的办法。但大多数解决方案都很模糊,不够灵活。在这方面,我认为这更为简洁和恰当。