Jackson - 映射的属性 为什么 Access.WRITE_ONLY 不起作用?

Mar*_*ira 8 java serialization jackson

为什么杰克逊不出示“财产ID”?

结果运行主程序

{id=1, name=Marcelo, email=test@gmail.com, password=123456, token=t1234, refre ...}
{id=1, name=Marcelo, email=test@gmail.com, password=null, enable=true}
propertie id > {"name":"Marcelo","email":"test@gmail.com","enable":true}
Run Code Online (Sandbox Code Playgroud)

问题在于映射的属性 id

@JsonProperty(access = Access.WRITE_ONLY) 当 Serialized 不产生属性和您的值时

jackson 2.13.0,但其他版本存在bug

在github中有项目模拟器问题 Bug Jackson Serialized property

在此显示代码

主类

package com;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class Main {

    private ObjectMapper model;

    public Main() {
        model = modelMapper();
    }

    public static void main(String[] args) {
        var main = new Main();
        var userEntity = new User();
        System.out.println(userEntity.toString());
        var user = main.getModel().convertValue(userEntity, UserDTO.class);
        System.out.println(user.toString());
        try {
            System.out.println(main.getModel().writeValueAsString(user));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public ObjectMapper getModel() {
        return model;
    }

    private ObjectMapper modelMapper() {
        var model = new ObjectMapper();
        model.registerModule(new SimpleModule());
        model.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        model.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
        model.configure(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID, false);
        return model;
    }
}
Run Code Online (Sandbox Code Playgroud)

用户DTO.类

package com;

import java.io.Serializable;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonProperty.Access;


public class UserDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonProperty(access = Access.WRITE_ONLY)
    private Long id;

    private String name;

    private String email;

    @JsonProperty(access = Access.READ_ONLY)
    private String password;

    private Boolean enable = false;

    public Long getId() {
        return id;
    }


    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }


    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Boolean getEnable() {
        return enable;
    }

    public void setEnable(Boolean enable) {
        this.enable = enable;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        UserDTO other = (UserDTO) obj;
        return Objects.equals(id, other.id);
    }


    @Override
    public String toString() {
        return "{id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", enable="
    + enable + "}";
    }
}
Run Code Online (Sandbox Code Playgroud)

用户类

package com;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id = 1L;

    private String name = "Marcelo";

    private String email = "test@gmail.com";

    private String password = "123456";

    private String token = "t1234";

    private String refresh = "t2345";

    private Boolean enable = true;

    private Boolean hashAble = true;

    private Date dataLastChange = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getRefresh() {
        return refresh;
    }

    public void setRefresh(String refresh) {
        this.refresh = refresh;
    }

    public Boolean getEnable() {
        return enable;
    }

    public void setEnable(Boolean enable) {
        this.enable = enable;
    }

    public Boolean getHashAble() {
        return hashAble;
    }

    public void setHashAble(Boolean hashAble) {
        this.hashAble = hashAble;
    }

    public Date getDataLastChange() {
        return dataLastChange;
    }

    public void setDataLastChange(Date dataLastChange) {
        this.dataLastChange = dataLastChange;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        return Objects.equals(id, other.id);
    }

    @Override
    public String toString() {
        return "{id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", token=" + token
    + ", refresh=" + refresh + ", enable=" + enable + ", hashAble=" + hashAble + ", dataLastChange="
    + dataLastChange + "}";
    }
}
Run Code Online (Sandbox Code Playgroud)

Joã*_*ias 4

参考文档对此非常清楚。WRITE_ONLY您可以阅读以下内容:

访问设置意味着该属性只能在反序列化时写入(设置),而在序列化时不会读取(获取),即该属性的值不包含在序列化中。

这清楚地表明,@JsonProperty(access = Access.WRITE_ONLY)在序列化包含它们的对象时(在您的情况下将 Java 对象转换为 JSON)注释的属性将不会被包含在内。

在我看来,您交换了访问类型。我想以下就是您想要的:

public class UserDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonProperty(access = Access.READ_ONLY)
    private Long id;

    private String name;

    private String email;

    @JsonProperty(access = Access.WRITE_ONLY)
    private String password;

    private Boolean enable = false;

    (...)
}
Run Code Online (Sandbox Code Playgroud)

鉴于您正在使用ObjectMapper映射 from Userto UserDTO,那么唯一的选择就是删除@JsonPropertyin ,id如下所示:

public class UserDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String name;

    private String email;

    @JsonProperty(access = Access.WRITE_ONLY)
    private String password;

    private Boolean enable = false;

    (...)
}
Run Code Online (Sandbox Code Playgroud)