【问题标题】:Is there an alternative to deserializing using setters and @JsonProperty for Spring有没有使用 setter 和 @JsonProperty for Spring 反序列化的替代方法
【发布时间】:2019-10-20 05:31:49
【问题描述】:

仅使用两个非常基本的示例.. 是否有将 JSON 反序列化为 POJO 的替代方法,我不需要创建设置器并且不需要在每个字段上声明 @JsonProperty?

@JsonProperty 看起来乏味且重复
Setter 似乎削弱了封装性。

使用设置器:

public class Person{
    private int age;
    private String name;

    public int getAge(){
        return age;
    }

    public void setAge(int age){
        this.age = age;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

使用@JsonProperty:

public class Person{
    @JsonProperty private int age;
    @JsonProperty private String name;

    public int getAge(){
        return age;
    }

    public String getName(){
        return name;
    }
}

【问题讨论】:

  • 你可以在构造函数上使用@JsonCreator,检查这些examples
  • chrsblck,即使使用Jsoncreator,自定义字段名也得使用JsonProperty。
  • 我问这个问题的主要原因是因为在我上一份工作中,我创建了 POJO,它会自动反序列化,没有任何注释。它只需要吸气剂(无论如何我都需要)。我应该,但没有,问这是怎么做到的。
  • @juice,只要json字段名和java类字段名相同,就可以轻松序列化/反序列化,无需任何jsonProperty。
  • 昨天我尝试将 JSON 反序列化为具有两个 BigDecimal 作为字段的对象时这样做了,除非我有设置器或使用 @JsonProperty 进行注释,否则它将无法工作。

标签: java spring spring-boot deserialization


【解决方案1】:

Jackson 具有自动检测功能,默认情况下只会反序列化所有 public 字段和所有 setter。这就是为什么如果所有字段都是私有的,如果没有设置器,则不会反序列化任何内容。

您可以使用@JsonAutoDetect 配置此自动检测功能,这样即使字段是私有的,它也会反序列化。所以这样一来,你就不需要再添加任何setter了。

按对象配置:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class Person{
    private int age;
    private String name;
}

全局配置,无需为每个对象进行配置:

ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

【讨论】:

  • 所以我只需要实例化一个 ObjectMapper 类并调用一个方法?我会把这段代码放在哪里?在主要方法中?无论如何在application.properties中配置它?我指的是全球解决方案。顺便说一句,这太棒了。
  • 没关系,我想通了。这太棒了。我只是将spring.jackson.visibility.field=ANY 放在 application.properties 文件中
【解决方案2】:

对于 Getter/Setter 尝试使用 Lombok,可以参考这个https://www.baeldung.com/intro-to-project-lombok

Lombok 的主要目标是减少样板代码,它非常有用。

关于@JsonProperty,如果你不使用注解标记属性,包将不知道它应该序列化还是反序列化。所以别无选择

【讨论】:

    【解决方案3】:

    另一种方法是创建一个构建器,其中only annotations that Jackson needs@JsonDeserialize@JsonPOJOBuilder,例如:

    @JsonDeserialize(builder = Person.Builder.class)
    public class Person {
      ...
      @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "")
      public static class Builder {
        ...
        public Builder age(final int age) {
          this.age = age;
          return this;
        }
        ...
      }
    }
    

    我认为这就像用 @JsonProperty 注释每个字段一样乏味,但就不变性而言,它比 setter 更好。

    【讨论】:

      猜你喜欢
      • 2015-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 2012-12-18
      • 2022-06-16
      • 2015-06-23
      相关资源
      最近更新 更多