我有一个发送到服务器或从服务器发送的用户对象。发送用户对象时,我不想将哈希密码发送给客户端。因此,我在password属性上添加了@JsonIgnore,但这也阻止了将其反序列化为密码,这使得在没有密码的情况下很难注册用户。
我如何才能仅申请@JsonIgnore序列化而不是反序列化?我正在使用Spring JSONView,因此对ObjectMapper没有太多控制。
我尝试过的事情:

@JsonIgnore添加到属性中
添加@JsonIgnore仅在getter方法上


#1 楼

确切的操作方法取决于您使用的Jackson版本。这在1.9版左右发生了变化,在此之前,您可以通过在getter中添加@JsonIgnore来实现。

您尝试过的方法:


在@JsonIgnore上添加只需执行getter方法


,然后将JSON“密码”字段名称的特定@JsonProperty注释添加到对象密码的setter方法中。

更多最新版本的Jackson已为READ_ONLY添加了WRITE_ONLYJsonProperty注释参数。因此,您也可以执行以下操作:

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


文档可以在这里找到。

评论


gist.github.com/thurloat/2510887 for Jackson JSON仅在反序列化时忽略

–哈达斯
2014年11月26日10:15



AFAIK,您仍然必须实现设置器并对其进行注释。我只想要获取器进行序列化。您所说的瞬态是什么?这是一个JPA注释AFAIK

–马特·布罗克威斯
2014年12月10日,0:37

另外,请确保从字段本身中删除@JsonProperty,否则它将覆盖您的getter / setter注释

–安东·索拉多(Anton Soradoi)
2015年3月4日15:14



@JsonProperty(访问权限= JsonProperty.Access.WRITE_ONLY)

– Mikhail Batcer
16-3-15的7:55

Jackson注释2.5没有更高版本的功能。杰克逊注释2.6.3确实

–radiantRazor
16-10-21在6:50



#2 楼

为此,我们需要做的是两个注释:


@JsonIgnore
@JsonProperty

在类成员及其吸气剂上使用@JsonIgnore,和其设置程序上的@JsonProperty。示例示例将有助于实现此目的:

class User {

    // More fields here
    @JsonIgnore
    private String password;

    @JsonIgnore
    public String getPassword() {
        return password;
    }

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


评论


这是杰克逊2.6.4对我唯一有效的方法。我尽力使用@JsonProperty(access = Access.WRITE_ONLY),但对我而言不起作用。

– cirovladimir
17年2月17日在21:37

#3 楼

从2.6版开始:一种更直观的方法是在字段上使用com.fasterxml.jackson.annotation.JsonProperty批注:

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


即使存在getter,该字段值也会从序列化中排除。 br />
JavaDoc说:

/**
 * Access setting that means that the property may only be written (set)
 * for deserialization,
 * but will not be read (get) on serialization, that is, the value of the property
 * is not included in serialization.
 */
WRITE_ONLY


如果您需要反过来,只需使用Access.READ_ONLY即可。

评论


我不明白为什么投票如此之少,这是解决此问题的一种优雅方法,就像一种魅力。无需注释getter,setter和field。只有字段。谢谢。

– CROSP
15年12月26日在16:22

自2.6版开始提供,请参见fastxml.github.io/jackson-annotations/javadoc/2.6/com/…

–丹尼尔·比尔(Daniel Beer)
15年12月27日在22:56

可能是2.6+用户的最佳答案。

–David Dossot
16-2-17的2:03

确保您没有使用org.codehaus.jackson.annotate导入。 @DanielBeer的解决方案适用于Jackson 2.6.3。既然Jackson已经更新,这应该是公认的答案。

–肯特·布尔
16 Mar 11 '16 at 0:17

#4 楼

就我而言,我让Jackson从Spring MVC控制器返回的对象自动(反序列化)对象(我在Spring 4.1.6中使用@RestController)。我必须使用com.fasterxml.jackson.annotation.JsonIgnore而不是org.codehaus.jackson.annotate.JsonIgnore,否则,它什么也没做。

评论


这是一个非常有用的答案,确实帮助我找到了为什么@JsonIgnore未被Jackson尊敬的原因...谢谢!

–克林特·伊斯特伍德
17年6月14日在21:13

#5 楼

"user": {
        "firstName": "Musa",
        "lastName": "Aliyev",
        "email": "klaudi2012@gmail.com",
        "passwordIn": "98989898", (or encoded version in front if we not using https)
        "country": "Azeribaijan",
        "phone": "+994707702747"
    }






@CrossOrigin(methods=RequestMethod.POST)
@RequestMapping("/public/register")
public @ResponseBody MsgKit registerNewUsert(@RequestBody User u){

        root.registerUser(u);

    return new MsgKit("registered");
}  






@Service
@Transactional
public class RootBsn {

    @Autowired UserRepository userRepo;

    public void registerUser(User u) throws Exception{

        u.setPassword(u.getPasswordIn());
        //Generate some salt and  setPassword (encoded -  salt+password)
        User u=userRepo.save(u);

        System.out.println("Registration information saved");
    }

}






    @Entity        
@JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"})
                    public class User implements Serializable {
                        private static final long serialVersionUID = 1L;

                        @Id
                        @GeneratedValue(strategy=GenerationType.AUTO)
                        private Long id;

                        private String country;

                        @Column(name="CREATED_BY")
                        private String createdBy;

                        private String email;

                        @Column(name="FIRST_NAME")
                        private String firstName;

                        @Column(name="LAST_LOGIN_DATE")
                        private Timestamp lastLoginDate;

                        @Column(name="LAST_NAME")
                        private String lastName;

                        @Column(name="MODIFICATION_DATE")
                        private Timestamp modificationDate;

                        @Column(name="MODIFIED_BY")
                        private String modifiedBy;

                        private String password;

                        @Transient
                        private String passwordIn;

                        private String phone;

                        @Column(name="RECORD_DATE")
                        private Timestamp recordDate;

                        private String salt;

                        private String status;

                        @Column(name="USER_STATUS")
                        private String userStatus;

                        public User() {
                        }
                // getters and setters
                }


评论


将来甚至对代码的工作方式进行简短描述也可能会有所帮助。

– KWILLIAMS
17年9月1日19:17在

好的 !!您在这里想做什么?获得更多选票?大声笑

–巴拉吉(Balaji)Boggaram Ramanarayan
18-10-12在18:40

#6 楼

解决此问题的另一种简便方法是在批注中使用参数allowSetters=true。这将允许将密码反序列化到您的dto中,但不会将其序列化为使用包含对象的响应主体。

示例:

@JsonIgnoreProperties(allowSetters = true, value = {"bar"})
class Pojo{
    String foo;
    String bar;
}


foobar都填充在对象中,但是只有foo被写入响应主体。

评论


那是我的错误,我没有意识到您已经纠正了代码段。查看您的更改,看来我在Groovy中的多年写作吸引了我,并且我对Java的翻译有些粗糙。抱歉!

–丹德利
19/12/25在22:58

#7 楼

您可以在类级别使用@JsonIgnoreProperties,然后将要忽略的变量放在json中的“值”参数中。对我有用。
@JsonIgnoreProperties(value = { "myVariable1","myVariable2" })
public class MyClass {
      private int myVariable1;,
      private int myVariable2;
}


#8 楼

您也可以像这样:
@JsonIgnore
@JsonProperty(access = Access.WRITE_ONLY)
private String password;

对我有用