提问者:小点点

反序列化时,是否可以使用映射的 Jackson Mixin 属性来创建 JSON 子类?


我已经用mixins为用户类正确地注释和映射了JSON输出,并为这些属性设置了适当的setters和getters:

 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" :
 {
     "first"  : "William",
     "middle" : "S",
     "last"   : "Preston"
 }

因此,为了简洁起见,我在这一点上撒了一点谎——上面提到的User是一个大型的、传统的DTO类,它不允许修改。

尽管mixin运行良好,但我们的客户更希望看到类似这样的内容:

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

     ...
 }

我再说一遍,DTO拒绝改变。理想情况下,我会重构DTO并正确执行。

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


共1个答案

匿名用户

由于不存在@JsonWrapped注释,我个人在此首选的解决方案是使用@JsonSerialize转换器功能(看起来您需要Jackson 2.3来实现这一点;2.2.2中支持注释,但我遇到了意外的运行时错误)。

基本上,转换器允许您执行从一种数据结构到另一种数据结构的序列化前转换。这使您可以使用简单的数据类,而不是为创建自定义序列化程序而烦恼。

首先,按照您希望的序列化方式为DTO建模:

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; }
    }
}

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

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

        }
    }

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

@JsonSerialize(converter = UserDto.Converter.class)
public interface UserMixin {
}