Java POJO中单个字段上内部对象值(JSON对象)的映射

Java POJO中单个字段上内部对象值(JSON对象)的映射,java,json,jackson,mapping,automapper,Java,Json,Jackson,Mapping,Automapper,我正在使用Jackson在javapojos上进行json映射。我想要的是将JSON的内部字段映射到我的父java POJO,并需要询问是否可以通过任何注释实现?我的JSON如下 { "email": "xyz@abc.com", "name": { "forenames": "John", "surname": "Doe" } } POJO是: public class Customer

我正在使用Jackson在javapojos上进行json映射。我想要的是将JSON的内部字段映射到我的父java POJO,并需要询问是否可以通过任何注释实现?我的JSON如下

{
        "email": "xyz@abc.com",
        "name": {
            "forenames": "John",
            "surname": "Doe"
    }
}        
POJO是:

 public class CustomerVo {

        @JsonProperty("last4")
        private String emailAddress; 

        /*is there any annotation available that I can use to concat
        fornames and surname in 'customeName' ?? */
        private String customerName; 

    }

提前感谢您的帮助。

据说有一种东西叫做
@JsonCreator

@JsonCreator
:用于指示构造函数或 静态工厂方法应用于创建值实例 在反序列化期间


例3.1。指向有一种叫做
@JsonCreator
的东西

@JsonCreator
:用于指示构造函数或 静态工厂方法应用于创建值实例 在反序列化期间


例3.1。指向文档。

首先,您可以编写一个类
CustomerName
,它将序列化您的属性。如果您不想实现一个单独的类,那么您需要定制
JsonDeserializer
JsonSerializer
(顺便说一句:代码比编写
CustomerName
类多一点)。比如说,

public class CustomerNameJsonSerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String customerName, JsonGenerator jg, SerializerProvider sp) throws IOException {
        jg.writeStartObject();

        jg.writeFieldName("forenames");
        jg.writeString(/* extract your forenames from customerName */);

        jg.writeFieldName("surname");
        jg.writeString(/* extract your surname from customerName */);

        jg.writeEndObject();
    }

}

public class CustomerNameJsonDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
        TreeNode tree = jp.readValueAsTree();
        TextNode forenames = (TextNode) tree.path("forenames");
        TextNode surname = (TextNode) tree.path("surname");

        return forenames.asText() + ":" + surname.asText();
    }

}

public class CustomerVo {

    @JsonProperty("last4")
    private String emailAddress; 

    @JsonProperty("name")
    @JsonSerialize(using = CustomerNameJsonSerializer.class)
    @JsonDeserialize(using = CustomerNameJsonDeserializer.class)
    private String customerName; 

}
公共类CustomerNameJsonSerializer扩展JsonSerializer{
@凌驾
public void serialize(字符串customerName、JsonGenerator jg、SerializerProvider sp)引发IOException{
jg.writeStartObject();
jg.writeFieldName(“名字”);
jg.writeString(/*从customerName*中提取您的名字*/);
jg.writeFieldName(“姓氏”);
jg.writeString(/*从客户姓名中提取您的姓氏*/);
jg.writeEndObject();
}
}
公共类CustomerNameJsonDeserializer扩展JsonDeserializer{
@凌驾
公共字符串反序列化(JsonParser jp,反序列化上下文dc)引发IOException{
TreeNode tree=jp.readValueAsTree();
TextNode forenames=(TextNode)tree.path(“forenames”);
TextNode姓氏=(TextNode)tree.path(“姓氏”);
返回forenames.astex()+“:“+姓氏.astex();
}
}
公共类客户服务{
@JsonProperty(“last4”)
私有字符串电子邮件地址;
@JsonProperty(“名称”)
@JsonSerialize(使用=CustomerNameJsonSerializer.class)
@JsonDeserialize(使用=CustomerNameJsonDeserializer.class)
私有字符串客户名称;
}

首先,您可以编写一个类
CustomerName
,它将序列化您的属性。如果您不想实现一个单独的类,那么您需要定制
JsonDeserializer
JsonSerializer
(顺便说一句:代码比编写
CustomerName
类多一点)。比如说,

public class CustomerNameJsonSerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String customerName, JsonGenerator jg, SerializerProvider sp) throws IOException {
        jg.writeStartObject();

        jg.writeFieldName("forenames");
        jg.writeString(/* extract your forenames from customerName */);

        jg.writeFieldName("surname");
        jg.writeString(/* extract your surname from customerName */);

        jg.writeEndObject();
    }

}

public class CustomerNameJsonDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
        TreeNode tree = jp.readValueAsTree();
        TextNode forenames = (TextNode) tree.path("forenames");
        TextNode surname = (TextNode) tree.path("surname");

        return forenames.asText() + ":" + surname.asText();
    }

}

public class CustomerVo {

    @JsonProperty("last4")
    private String emailAddress; 

    @JsonProperty("name")
    @JsonSerialize(using = CustomerNameJsonSerializer.class)
    @JsonDeserialize(using = CustomerNameJsonDeserializer.class)
    private String customerName; 

}
公共类CustomerNameJsonSerializer扩展JsonSerializer{
@凌驾
public void serialize(字符串customerName、JsonGenerator jg、SerializerProvider sp)引发IOException{
jg.writeStartObject();
jg.writeFieldName(“名字”);
jg.writeString(/*从customerName*中提取您的名字*/);
jg.writeFieldName(“姓氏”);
jg.writeString(/*从客户姓名中提取您的姓氏*/);
jg.writeEndObject();
}
}
公共类CustomerNameJsonDeserializer扩展JsonDeserializer{
@凌驾
公共字符串反序列化(JsonParser jp,反序列化上下文dc)引发IOException{
TreeNode tree=jp.readValueAsTree();
TextNode forenames=(TextNode)tree.path(“forenames”);
TextNode姓氏=(TextNode)tree.path(“姓氏”);
返回forenames.astex()+“:“+姓氏.astex();
}
}
公共类客户服务{
@JsonProperty(“last4”)
私有字符串电子邮件地址;
@JsonProperty(“名称”)
@JsonSerialize(使用=CustomerNameJsonSerializer.class)
@JsonDeserialize(使用=CustomerNameJsonDeserializer.class)
私有字符串客户名称;
}

我想知道您的
CustomerVo
中是否有
名称
对象。如果您这样做,您可以实现一个getter,它将返回
姓氏+姓氏
。您可能必须使用自定义反序列化程序。@Schrieveslaach但为此,我必须为名称{}创建一个新类,我不想这样做,而是想将姓氏和姓氏映射到CustomerVo的customerName@Thomas怎么做?对于这个特定的案例,快速谷歌搜索的第一个结果我想知道您的
CustomerVo
中是否有
Name
对象。如果您这样做,您可以实现一个getter,它将返回
姓氏+姓氏
。您可能必须使用自定义反序列化程序。@Schrieveslaach但为此,我必须为名称{}创建一个新类,我不想这样做,而是想将姓氏和姓氏映射到CustomerVo的customerName@Thomas怎么做?对于这个特定的案例,谷歌快速搜索的第一个结果是正确的,它的代码要多一点。但谢谢,这对我来说是一个学习曲线,我感谢你的帮助。只有一个问题:你能提一下我应该考虑使用自定义序列化器而不是编写类的情况吗?我认为当我们有非常复杂的json时,我们应该使用它,否则最好编写类?有意义吗?@ManinGreen当我想从库(我不能修改的类)序列化外部对象时,我使用自定义序列化程序。当我序列化自己的类时,通常不使用自定义序列化程序。创建相应的类可以为您提供更多的抽象和控制。在您的示例中,您将两个属性
forenames
name
保留在单独的属性中。然后,您不能意外地将它们混合在一起。@ManinGreen但是,有一个用例:如果您有非常大的对象列表,您可以使用序列化程序找到更压缩的JSON表示法。您是对的,它的代码要多一点。但谢谢,这对我来说是一个学习曲线,我感谢你的帮助。只有一个问题:你能提一下我应该考虑使用习惯的情况吗?