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

标签 java json serialization jackson

我有这个 JSON 要反序列化:

{
    "first-name": "Alpha",
    "last-name": "Beta",
    "gender": "m"
}

我想将它序列化为 2 种不同的格式:

[A]

{
    "first-name": "Alpha",
    "last-name": "Beta",
    "gender": "m"
}

[B]

{
    "firstName": "Alpha",
    "lastName": "Beta",
    "gender": "m"
}

我可以将其序列化为一种格式:仅 [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 的信息 http://www.baeldung.com/jackson-json-view-annotation (“5. 自定义 JSON View ”部分)但它仅更改其值。我想更改字段名称,如上例所示。任何人都可以对此发表见解吗?

最佳答案

我不确定我是否完全理解你的问题,但据我所知,你可以做这样的事情来实现不同的序列化。

创建一个自定义注释来保存所有可能的不同序列化选项:

@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();
    }
}

现在您可以序列化您的对象,同时考虑属性名称的不同格式:

public static void main(String[] args) throws IOException {
    Bar bar1 = new Bar("first", "last", "m", "A");
    Bar bar2 = new Bar("first", "last", "m", "B");

    ObjectMapper mapper = new ObjectMapper();
    String json1 = mapper.writeValueAsString(bar1);
    String json2 = mapper.writeValueAsString(bar2);

    System.out.println(json1);
    System.out.println(json2);

}

输出:

{"first-name":"first","last-name":"last","gender-x":"m"}
{"firstName":"first","lastName":"last","gender":"m"}

当然,上面的序列化程序只适用于 Bar 对象,但这可以通过在父类(super class)上使用 abstract String getFormat(); 继承并更改自定义序列化程序以接受父类(super class)来轻松解决类型,而不是 Bar。

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

关于java - Jackson 将字段序列化为不同的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36646098/

相关文章:

最方便表示关系数据库的Java对象结构

javascript - Coinmarketcap API 不工作

现有协议(protocol)的 C++ 序列化库

c# - 使用 DataContract Name 属性重命名 WCF 泛型类

java - 如何获取新的ArrayList数据?

java - 具有多个参数的 JPA 标准 API

jQuery DataTables 渲染列数据

java - 为 Kafka 流上的窗口数据创建 SerDes

java - 获取 BorderPane 中中心空间的宽度和高度 (JavaFX 2)

java - MapBox 无法将 JSONObject 转换为 JSONArray