Java 仅在使用Jackson进行序列化或反序列化期间,选择性地@JsonIgnore不可变访问器方法
这绝对不是复制品。这个问题是相同的,但在这个问题的背景下 当模型(DTO/DAO)被修饰为不可变时,我无法在序列化期间选择性地@JsonIgnore其中一个属性。假设我们有一个UserDto,它被定义为不可变的,如下所示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
@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影响字段的序列化或反序列化。