我可以使用映射的Jackson Mixin属性在反序列化时创建JSON子类吗?

时间:2014-06-10 20:51:30

标签: java json jackson pojo

我正确地注释了JSON输出并使用mixins为User类映射,并为这些属性设置了适当的setter和getter:

 public class User {
      String first;
      String middle;
      String last;

      ...
 }

当我使用我的Mixin时:

 public interface UserMixin {
     @JsonProperty("first")
     void setFirst(String first);

     @JsonProperty("middle")
     void setMiddle(String middle);

     @JsonProperty("last")
     void setLast(String last);
 }

注册mixin并使用ObjectMapper编写User类后,我得到:

 "User" :
 {
     "first"  : "William",
     "middle" : "S",
     "last"   : "Preston"
 }

所以到目前为止,为了简洁起见,我撒谎了一点 - 上面引用的用户是一个很难修改的大型遗留DTO课程。

而且,虽然mixin工作得很好,但我们的客户宁愿看到类似的东西:

 "User" :
 {
     "Name" : 
     {
         "first"  : "William",
         "middle" : "S",
         "last"   : "Preston"
     }

     ...
 }

我再说一遍,DTO抵制变革。理想情况下,我会重构DTO并正确执行。

我想我想问的是 - 我是否可以使用Mixin / Annotation的一些组合来从User类中已有的数据中对“Name”进行子类化?没有Name子类......但是存在以这种格式“写出”JSON所需的所有部分。

1 个答案:

答案 0 :(得分:1)

缺少@JsonWrapped注释的存在,我个人首选的解决方案是使用converter的{​​{1}}功能(看起来你需要Jackson 2.3+这个;注释在2.2.2中得到支持,但我得到了意外的运行时错误)。

基本上,@JsonSerialize允许您从一个数据结构到另一个数据结构进行预序列化转换。这使您可以使用简单的数据类,而不是创建自定义序列化器。

首先,为您的DTO建模您希望如何序列化:

converter

接下来,创建一个简单的Converter类(我将其嵌套在UserDto中):

public static class UserDto {
    private final Name name;

    private UserDto(Name name) { this.name = name; }

    public static UserDto fromUser(User user) {
        return new UserDto(Name.fromUser(user));
    }

    public Name getName() { return name; }

    public static class Name {
        private final String first;
        private final String middle;
        private final String last;

        private Name(String first, String middle, String last) {
            this.first = first;
            this.middle = middle;
            this.last = last;
        }

        public static Name fromUser(User user) {
            return new Name(user.getFirst(), user.getMiddle(), user.getLast());
        }

        public String getFirst() { return first; }
        public String getMiddle() { return middle; }
        public String getLast() { return last; }
    }
}

然后,在mixin中使用该转换器类:

    public static class Converter extends StdConverter<User, UserDto> {
        @Override
        public UserDto convert(User value) {
            return UserDto.fromUser(value);

        }
    }