Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅在使用Jackson进行序列化或反序列化期间,选择性地@JsonIgnore不可变访问器方法_Java_Jackson_Jackson Databind_Immutables Library - Fatal编程技术网

Java 仅在使用Jackson进行序列化或反序列化期间,选择性地@JsonIgnore不可变访问器方法

Java 仅在使用Jackson进行序列化或反序列化期间,选择性地@JsonIgnore不可变访问器方法,java,jackson,jackson-databind,immutables-library,Java,Jackson,Jackson Databind,Immutables Library,这绝对不是复制品。这个问题是相同的,但在这个问题的背景下 当模型(DTO/DAO)被修饰为不可变时,我无法在序列化期间选择性地@JsonIgnore其中一个属性。假设我们有一个UserDto,它被定义为不可变的,如下所示 @Value.Immutable @Value.Style(defaults = @Value.Immutable(copy = false), init = "set*") @JsonSerialize(as = ImmutableUserDto.class) @JsonDe

这绝对不是复制品。这个问题是相同的,但在这个问题的背景下

当模型(DTO/DAO)被修饰为不可变时,我无法在序列化期间选择性地@JsonIgnore其中一个属性。假设我们有一个UserDto,它被定义为不可变的,如下所示

@Value.Immutable
@Value.Style(defaults = @Value.Immutable(copy = false), init = "set*")
@JsonSerialize(as = ImmutableUserDto.class)
@JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {

    @JsonProperty("id")
    @Value.Default
    public int getId() {
        return 0;
    }

    @JsonProperty("username")
    public abstract String getUsername();

    @JsonProperty("email")
    public abstract String getEmail();

    @JsonProperty("password")
    public abstract String getPassword();
}
我相信,在序列化过程中,我们希望忽略服务响应中的
密码是公平的

如果我们使用的是一个简单的类,那么在不使用不可变项的情况下,有很多方法可以实现这一点。例如-仅使用
@JsonIgnore
注释getter。或者,如果可能的话,定义一个不同的访问器方法(没有get前缀的方法),只定义常规的setter方法。。。等等

如果我对密码的Immutables访问器方法进行相同的尝试,如下所示:

@Value.Immutable
@Value.Style(defaults = @Value.Immutable(copy = false), init = "set*")
@JsonSersonIgnoreialize(as = ImmutableUserDto.class)
@JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {

    ....

    @JsonProperty("password")
    @JsonIgnore
    public abstract String getPassword();
}
然后,生成的ImmutableUserDto在getter和setter上添加@JsonIgnore,如下所示

@Generated(from = "UserDto", generator = "Immutables")
@SuppressWarnings({"all"})
@ParametersAreNonnullByDefault
@javax.annotation.Generated("org.immutables.processor.ProxyProcessor")
@Immutable
@CheckReturnValue
public final class ImmutableUserDto extends UserDto {
  ...
  ...
  private final String password;

  ...
  ...

  /**
   * @return The value of the {@code password} attribute
   */
  @JsonProperty("password")
  @JsonIgnore
  @Override
  public String getPassword() {
    return password;
  }

  ...
  ...
  ...

  @Generated(from = "UserDto", generator = "Immutables")
  @NotThreadSafe
  public static final class Builder {

    ...
    ...

    private String password;

    @JsonProperty("password")
    @JsonIgnore
    public final Builder setPassword(String password) {
      this.password = password;
      return this;
    }
  }
}
序列化将按预期工作。
password
属性将从JSON中排除。但当我尝试反序列化时,会出现以下错误:

java.lang.IllegalStateException: Cannot build UserDto, some of the required attributes are not set [password]
这是显而易见的,因为Immutables也向setter添加了
@JsonIgnore

这本书帮不了什么忙。在他们的“需要注意的事情”一节中,只提到了以下关于
@JsonIgnore

如果使用@JsonIgnore,您应该显式地创建一个属性 非强制性。在不可变中,属性可以声明为 通过@Nullable、Optional或@Value.Default执行非强制性操作,这些都是 它们的效果不同,我们不会自动得出任何结果

使用
@Nullable
可选
@值。对于
密码
等字段,默认值
没有任何用处

我查看了他们GitHub页面上的问题列表,发现有一个问题,但用户要求的是一个稍微不同的用例,使用@Nullable可以解决这个问题,但在我的情况下,这个问题不起作用

我也试着使用其中一个答案。仍然导致相同的错误


看起来Immutables库不支持这一点。我自己创造了一个梦想。一旦我从用户那里得到一些关于SOF的反馈,我可能会创建一个。我不得不使用@benarena在本文中给出的建议。但是,我必须显式地指定属性的value属性和Access属性

@JsonProperty(value=“password”,access=JsonProperty.access.WRITE_ONLY)
解决了这个问题

不可变类的外观如下所示:

@Value.Immutable
@Value.Style(defaults = @Value.Immutable(copy = false), init = "set*")
@JsonSersonIgnoreialize(as = ImmutableUserDto.class)
@JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {

    ....

    @JsonProperty(value = "password", access = JsonProperty.Access.WRITE_ONLY)
    public abstract String getPassword();
}

您应该能够使用链接到的
@JsonProperty(access=JsonProperty.access.WRITE_)
注释,以避免序列化密码值。我已成功地将其用于不可变项,通过Jackson影响字段的序列化或反序列化。