Don't know, looks like transient
attribute modifier plus PROPAGATE_TRANSIENT_MARKER
just does it. Deserialization is straight forward. There's some fuss with the transient marker during serialization, though. You need to provide getters for the fields, otherwise you'll be stuck with an exception "Unrecognized field ... not marked as ignorable".
Reacting to additional requirements I added a version using jackson mixins. Note that the mixin version produces json with an empty password field, while the PROPAGATE_TRANSIENT_MARKER version produces no field at all.
PROPAGATE_TRANSIENT_MARKER version
public class SerializeDeserializeAttributes {
private final ObjectMapper mapper = new ObjectMapper();
public <T> T fromJson(String json, Class<T> c) throws IOException {
synchronized (mapper) {
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false);
return mapper.readValue(json, c);
}
}
public String toJson(Object o) throws JsonProcessingException {
synchronized (mapper) {
mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
return mapper.writeValueAsString(o);
}
}
private static final String jsonFull = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"a\",\"width\":1,\"height\":1}";
private static final String jsonPartial = "{\"name\":\"A\",\"email\":\"a@a\",\"width\":1,\"height\":1}";
private static final User user = new User("A", "a@a", "a", 1, 1);
@Test
public void serializeDeserialize() throws IOException {
assertEquals(user, fromJson(jsonFull, User.class));
assertEquals(jsonPartial, toJson(user));
assertEquals(user, fromJson(jsonFull, User.class));
assertEquals(jsonPartial, toJson(user));
}
}
Mixin version
public class SerializeDeserializeAttributesMixin {
public abstract class UserMixin {
@JsonSerialize(using = PwdSerializer.class)
transient String password;
}
static class PwdSerializer extends StdSerializer<String> {
public PwdSerializer() {
this(String.class);
}
private PwdSerializer(Class<String> t) {
super(t);
}
@Override
public void serialize(String s, JsonGenerator jg, SerializerProvider sp) throws IOException {
jg.writeString("");
}
}
private static final String jsonFull = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"a\",\"width\":1,\"height\":1}";
private static final String jsonPartialMixin = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"\",\"width\":1,\"height\":1}";
private static final User user = new User("A", "a@a", "a", 1, 1);
private static final ObjectMapper mapperMixin = new ObjectMapper();
static {
mapperMixin.addMixIn(User.class, UserMixin.class);
}
@Test
public void serializeDeserializeUsingMixin() throws IOException {
assertEquals(user, mapperMixin.readValue(jsonFull, User.class));
assertEquals(jsonPartialMixin, mapperMixin.writeValueAsString(user));
}
}
That's the User class.
class User {
private String name;
private String email;
private transient String password;
private int width;
private int height;
public User() {
}
User(String name, String email, String password, int width, int height) {
this.name = name;
this.email = email;
this.password = password;
this.width = width;
this.height = height;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Float.compare(user.width, width) == 0 &&
Float.compare(user.height, height) == 0 &&
Objects.equals(name, user.name) &&
Objects.equals(email, user.email) &&
Objects.equals(password, user.password);
}
@Override
public int hashCode() {
return Objects.hash(name, email, password, width, height);
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
", width=" + width +
", height=" + height +
'}';
}
}