【问题标题】:Can I use mapped Jackson Mixin properties to create a JSON subclass when deserializing?我可以在反序列化时使用映射的 Jackson Mixin 属性来创建 JSON 子类吗?
【发布时间】:2014-06-10 20:51:29
【问题描述】:

我已经为 User 类正确注释和映射 JSON 输出,并为这些属性使用适当的 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"
 }

至此,为简洁起见,我撒了一点谎 - 上面提到的 User 是一个大型的遗留 DTO 类,它对修改有抵抗力。

而且,虽然 mixin 效果很好,但我们的客户更愿意看到类似的东西:

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

     ...
 }

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

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

【问题讨论】:

  • 我认为你能做的最好的事情就是创建自己的JsonSerializer
  • 反其道而行之是微不足道的 - @JsonUnwrapped。不幸的是,据我所知,不支持自动包装该值。

标签: java json jackson pojo


【解决方案1】:

缺少@JsonWrapped 注释的存在,我个人首选的解决方案是使用@JsonSerializeconverter 功能(看起来你需要Jackson 2.3+;注释在2.2 中受支持.2 但我遇到了意外的运行时错误)。

基本上,converter 允许您进行从一种数据结构到另一种数据结构的预序列化转换。这让您可以使用简单的数据类,而不必费力创建自定义序列化程序。

首先,为您的 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; }
    }
}

接下来,创建一个简单的 Converter 类(我将它嵌套在 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 {
}

【讨论】:

  • 这行得通:在遗留用户 DTO 之间创建一个临时 POJO 允许我们转换为我们需要的格式,并简化一些我们不需要的遗留问题。谢谢!
猜你喜欢
  • 2017-10-03
  • 1970-01-01
  • 2014-01-09
  • 2021-06-23
  • 2018-02-28
  • 1970-01-01
  • 2019-01-20
  • 2020-01-25
  • 1970-01-01
相关资源
最近更新 更多