Asymmetric serialization and deserialization using Jackson

江枫思渺然 提交于 2019-12-22 09:16:52

问题


I am using Jackson to serialize and deserialize data for a RESTful API. I'd like to have a REST resource (/comments) that allows to POST comments as well as to GET a list of comments.

Here's a (simplified) example of what gets posted to /comments.

{"text":"Text","author":"Paul","email":"paul@example.org"}

Here's what the result of GET /comments should look like:

[{"text":"Text","author":"Paul","emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]

Since email addresses shouldn't be visible to anyone, I decided to return only a MD5 hash of the email addresses in the response.

I have created a simple POJO class Comment that has fields with getters and setters for text, author, email, and emailHash.

Now, when I serialize the result, what I get is the following:

[{"text":"Text","author":"Paul","email":null,"emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]

But I really don't like email to be returned as null here. It rather shouldn't be included at all.

Using the annotation @JsonIgnore on that field will also ignore it on deserialization. Do I have to create two classes, say CreationComment and ResultComment with a super-class Comment that shares common fields or is there a way that avoids creating additional classes?


回答1:


You don't have to create 2 classes at all. With Jackson you have full control of the behavior of a property during serialization and deserialization using annotations, with @JsonIgnorein the getter you prevent the property from being serialized in your Json response and using @JsonProperty annotation in the setter the property will be set during deserialization. The code will look like this:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Comment {

    private String author;

    private String email;

    @JsonIgnore
    public String getEmail() {
        return email;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        Comment comment = new Comment();
        comment.setAuthor("anAuthor");
        comment.setEmail("email@example.com");

        try {
            System.out.println(objectMapper.writeValueAsString(comment));

            String json = "{\"author\":\"anAuthor\",\"email\":\"another@email.com\"}";
            Comment fromJson = objectMapper.readValue(json, Comment.class);

            System.out.println("Result from Json: author= " + fromJson.getAuthor() + ", email= " + fromJson.getEmail());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

The output after running the main() method to test the solution:

{"author":"anAuthor"}

Result from Json: author= anAuthor, email= another@email.com

Hope it helps,

Jose Luis




回答2:


You can put @JsonIgnore on getEmail to prevent it from being serialized to JSON and use @JsonCreator to indicate to Jackson a constructor to use for deserialization. The constructor would then only accept an email property and would hash and assign to your emailHash field.

You can put a @JsonInclude annotation on your Comment class to prevent serialization of null fields too.

Your class would probably end up looking something like this:

@JsonInclude(Include.NON_NULL)
public class Comment {
    private final String email;
    private final String emailHash;

    @JsonCreator
    public Comment(@JsonProperty("email") String email) {
        this.email = email;
        this.emailHash = MD5.hash(email);
    }

    @JsonIgnore
    public String getEmail() {
        return email;
    }

    public String getEmailHash() {
        return emailHash;
    }
}


来源:https://stackoverflow.com/questions/30134298/asymmetric-serialization-and-deserialization-using-jackson

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!