bring jackson back
This commit is contained in:
parent
bfe5c96f77
commit
dc220b25ff
|
@ -0,0 +1,9 @@
|
|||
## Jackson Custom Conversions
|
||||
|
||||
This module contains articles about Jackson custom conversions.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Jackson – Custom Serializer](https://www.baeldung.com/jackson-custom-serialization)
|
||||
- [Getting Started with Custom Deserialization in Jackson](https://www.baeldung.com/jackson-deserialization)
|
||||
- [Serialize Only Fields that meet a Custom Criteria with Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria)
|
||||
- [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer)
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jackson-custom-conversions</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>jackson-custom-conversions</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.ossez</groupId>
|
||||
<artifactId>jackson-modules</artifactId>
|
||||
<version>0.0.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-joda</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>jackson-custom-conversions</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.defaultserializercustomserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class FolderSerializerWithCallingOwnSerializer extends StdSerializer<Folder> {
|
||||
|
||||
public FolderSerializerWithCallingOwnSerializer() {
|
||||
super(Folder.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("name", value.getName());
|
||||
|
||||
provider.defaultSerializeField("files", value.getFiles(), gen);
|
||||
|
||||
provider.defaultSerializeField("details", value, gen);
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.defaultserializercustomserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class FolderSerializerWithDefaultSerializerStored extends StdSerializer<Folder> {
|
||||
|
||||
private final JsonSerializer<Object> defaultSerializer;
|
||||
|
||||
public FolderSerializerWithDefaultSerializerStored(JsonSerializer<Object> defaultSerializer) {
|
||||
super(Folder.class);
|
||||
this.defaultSerializer = defaultSerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("name", value.getName());
|
||||
|
||||
provider.defaultSerializeField("files", value.getFiles(), gen);
|
||||
|
||||
gen.writeFieldName("details");
|
||||
defaultSerializer.serialize(value, gen, provider);
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.defaultserializercustomserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class FolderSerializerWithInternalObjectMapper extends StdSerializer<Folder> {
|
||||
|
||||
public FolderSerializerWithInternalObjectMapper() {
|
||||
super(Folder.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("name", value.getName());
|
||||
|
||||
// we access internal mapper to delegate the serialization of File list
|
||||
ObjectMapper mapper = (ObjectMapper) gen.getCodec();
|
||||
|
||||
gen.writeFieldName("files");
|
||||
String stringValue = mapper.writeValueAsString(value.getFiles());
|
||||
gen.writeRawValue(stringValue);
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.defaultserializercustomserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class FolderSerializerWithSerializerProvider extends StdSerializer<Folder> {
|
||||
|
||||
public FolderSerializerWithSerializerProvider() {
|
||||
super(Folder.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("name", value.getName());
|
||||
|
||||
// we delegate the File list serialization to its default serializer
|
||||
provider.defaultSerializeField("files", value.getFiles(), gen);
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class ActorJackson {
|
||||
|
||||
private String imdbId;
|
||||
private Date dateOfBirth;
|
||||
private List<String> filmography;
|
||||
|
||||
public ActorJackson() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ActorJackson(String imdbId, Date dateOfBirth, List<String> filmography) {
|
||||
super();
|
||||
this.imdbId = imdbId;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
this.filmography = filmography;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActorJackson [imdbId=" + imdbId + ", dateOfBirth=" + formatDateOfBirth() + ", filmography=" + filmography + "]";
|
||||
}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public Date getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(Date dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public List<String> getFilmography() {
|
||||
return filmography;
|
||||
}
|
||||
|
||||
public void setFilmography(List<String> filmography) {
|
||||
this.filmography = filmography;
|
||||
}
|
||||
|
||||
private String formatDateOfBirth() {
|
||||
final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.US);
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
return formatter.format(dateOfBirth);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
public class Item {
|
||||
public int id;
|
||||
public String itemName;
|
||||
public User owner;
|
||||
|
||||
public Item() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Item(final int id, final String itemName, final User owner) {
|
||||
this.id = id;
|
||||
this.itemName = itemName;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.node.IntNode;
|
||||
|
||||
public class ItemDeserializer extends StdDeserializer<Item> {
|
||||
|
||||
private static final long serialVersionUID = 1883547683050039861L;
|
||||
|
||||
public ItemDeserializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ItemDeserializer(final Class<?> vc) {
|
||||
super(vc);
|
||||
}
|
||||
|
||||
/**
|
||||
* {"id":1,"itemNr":"theItem","owner":2}
|
||||
*/
|
||||
@Override
|
||||
public Item deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
final JsonNode node = jp.getCodec()
|
||||
.readTree(jp);
|
||||
final int id = (Integer) ((IntNode) node.get("id")).numberValue();
|
||||
final String itemName = node.get("itemName")
|
||||
.asText();
|
||||
final int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue();
|
||||
|
||||
return new Item(id, itemName, new User(userId, null));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.node.IntNode;
|
||||
|
||||
public class ItemDeserializerOnClass extends StdDeserializer<ItemWithDeserializer> {
|
||||
|
||||
private static final long serialVersionUID = 5579141241817332594L;
|
||||
|
||||
public ItemDeserializerOnClass() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ItemDeserializerOnClass(final Class<?> vc) {
|
||||
super(vc);
|
||||
}
|
||||
|
||||
/**
|
||||
* {"id":1,"itemNr":"theItem","owner":2}
|
||||
*/
|
||||
@Override
|
||||
public ItemWithDeserializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
final JsonNode node = jp.getCodec()
|
||||
.readTree(jp);
|
||||
final int id = (Integer) ((IntNode) node.get("id")).numberValue();
|
||||
final String itemName = node.get("itemName")
|
||||
.asText();
|
||||
final int userId = (Integer) ((IntNode) node.get("owner")).numberValue();
|
||||
|
||||
return new ItemWithDeserializer(id, itemName, new User(userId, null));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
||||
@JsonDeserialize(using = ItemDeserializerOnClass.class)
|
||||
public class ItemWithDeserializer {
|
||||
public final int id;
|
||||
public final String itemName;
|
||||
public final User owner;
|
||||
|
||||
public ItemWithDeserializer(final int id, final String itemName, final User owner) {
|
||||
this.id = id;
|
||||
this.itemName = itemName;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Movie {
|
||||
|
||||
private String imdbId;
|
||||
private String director;
|
||||
private List<ActorJackson> actors;
|
||||
|
||||
public Movie(String imdbId, String director, List<ActorJackson> actors) {
|
||||
super();
|
||||
this.imdbId = imdbId;
|
||||
this.director = director;
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
public Movie() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]";
|
||||
}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public String getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setDirector(String director) {
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
public List<ActorJackson> getActors() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public void setActors(List<ActorJackson> actors) {
|
||||
this.actors = actors;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
public class User {
|
||||
public int id;
|
||||
public String name;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public User(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
public class Item {
|
||||
public int id;
|
||||
public String itemName;
|
||||
public User owner;
|
||||
|
||||
public Item() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Item(final int id, final String itemName, final User owner) {
|
||||
this.id = id;
|
||||
this.itemName = itemName;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class ItemSerializer extends StdSerializer<Item> {
|
||||
|
||||
private static final long serialVersionUID = 6739170890621978901L;
|
||||
|
||||
public ItemSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ItemSerializer(final Class<Item> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serialize(final Item value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeStartObject();
|
||||
jgen.writeNumberField("id", value.id);
|
||||
jgen.writeStringField("itemName", value.itemName);
|
||||
jgen.writeNumberField("owner", value.owner.id);
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class ItemSerializerOnClass extends StdSerializer<ItemWithSerializer> {
|
||||
|
||||
private static final long serialVersionUID = -1760959597313610409L;
|
||||
|
||||
public ItemSerializerOnClass() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ItemSerializerOnClass(final Class<ItemWithSerializer> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeStartObject();
|
||||
jgen.writeNumberField("id", value.id);
|
||||
jgen.writeStringField("itemName", value.itemName);
|
||||
jgen.writeNumberField("owner", value.owner.id);
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize(using = ItemSerializerOnClass.class)
|
||||
public class ItemWithSerializer {
|
||||
public final int id;
|
||||
public final String itemName;
|
||||
public final User owner;
|
||||
|
||||
public ItemWithSerializer(final int id, final String itemName, final User owner) {
|
||||
this.id = id;
|
||||
this.itemName = itemName;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
public class User {
|
||||
public int id;
|
||||
public String name;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public User(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
public class Address implements Hidable {
|
||||
private String city;
|
||||
private String country;
|
||||
private boolean hidden;
|
||||
|
||||
public Address(final String city, final String country, final boolean hidden) {
|
||||
super();
|
||||
this.city = city;
|
||||
this.country = country;
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public void setHidden(final boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties("hidden")
|
||||
public interface Hidable {
|
||||
boolean isHidden();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
public class HidableSerializer extends JsonSerializer<Hidable> {
|
||||
|
||||
private JsonSerializer<Object> defaultSerializer;
|
||||
|
||||
public HidableSerializer(final JsonSerializer<Object> serializer) {
|
||||
defaultSerializer = serializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final Hidable value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
if (value.isHidden())
|
||||
return;
|
||||
defaultSerializer.serialize(value, jgen, provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(final SerializerProvider provider, final Hidable value) {
|
||||
return (value == null || value.isHidden());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
|
||||
@JsonFilter("myFilter")
|
||||
public class MyDtoWithFilter {
|
||||
|
||||
private String stringValue;
|
||||
private int intValue;
|
||||
private boolean booleanValue;
|
||||
|
||||
public MyDtoWithFilter() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyDtoWithFilter(final String stringValue, final int intValue, final boolean booleanValue) {
|
||||
super();
|
||||
|
||||
this.stringValue = stringValue;
|
||||
this.intValue = intValue;
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public String getStringValue() {
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
public void setStringValue(final String stringValue) {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public int getIntValue() {
|
||||
return intValue;
|
||||
}
|
||||
|
||||
public void setIntValue(final int intValue) {
|
||||
this.intValue = intValue;
|
||||
}
|
||||
|
||||
public boolean isBooleanValue() {
|
||||
return booleanValue;
|
||||
}
|
||||
|
||||
public void setBooleanValue(final boolean booleanValue) {
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
public class Person implements Hidable {
|
||||
private String name;
|
||||
private Address address;
|
||||
private boolean hidden;
|
||||
|
||||
public Person(final String name, final Address address, final boolean hidden) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(final Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public void setHidden(final boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
package com.baeldung.defaultserializercustomserializer;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
|
||||
public class CallingDefaultSerializerUnitTest {
|
||||
|
||||
private ObjectMapper mapper;
|
||||
private Folder mockFolder;
|
||||
private TypeReference<HashMap<String, Object>> mapType;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
mapType = new TypeReference<HashMap<String, Object>>() {
|
||||
};
|
||||
|
||||
mapper = new ObjectMapper();
|
||||
|
||||
mockFolder = new Folder();
|
||||
mockFolder.setId(1L);
|
||||
mockFolder.setName("Root Folder");
|
||||
mockFolder.setOwner("root");
|
||||
mockFolder.setCreated(Date.from(Instant.now().minusSeconds(60)));
|
||||
mockFolder.setModified(Date.from(Instant.now().minusSeconds(30)));
|
||||
mockFolder.setLastAccess(Date.from(Instant.now()));
|
||||
|
||||
File file1 = new File();
|
||||
file1.setId(1L);
|
||||
file1.setName("File 1");
|
||||
|
||||
File file2 = new File();
|
||||
file2.setId(2L);
|
||||
file2.setName("File 2");
|
||||
|
||||
List<File> files = new ArrayList<>();
|
||||
files.add(file1);
|
||||
files.add(file2);
|
||||
mockFolder.setFiles(files);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFolder_whenSerialized_onlyNameAndFilesFieldsSerialized() throws IOException {
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(new FolderSerializer());
|
||||
mapper.registerModule(module);
|
||||
|
||||
String json = mapper.writeValueAsString(mockFolder);
|
||||
|
||||
HashMap<String, Object> actual = mapper.readValue(json, mapType);
|
||||
|
||||
assertTrue(actual.containsKey("name"));
|
||||
assertTrue(actual.containsKey("files"));
|
||||
assertEquals(mockFolder.getName(), actual.get("name"));
|
||||
|
||||
List actualFiles = (List) actual.get("files");
|
||||
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFolder_whenSerializedWithSerializerProvider_onlyNameAndFilesFieldsSerialized() throws IOException {
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(new FolderSerializerWithSerializerProvider());
|
||||
mapper.registerModule(module);
|
||||
|
||||
String json = mapper.writeValueAsString(mockFolder);
|
||||
|
||||
HashMap<String, Object> actual = mapper.readValue(json, mapType);
|
||||
|
||||
assertTrue(actual.containsKey("name"));
|
||||
assertTrue(actual.containsKey("files"));
|
||||
assertEquals(mockFolder.getName(), actual.get("name"));
|
||||
|
||||
List actualFiles = (List) actual.get("files");
|
||||
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFolder_whenSerializedWithInternalObjectMapper_onlyNameAndFilesFieldsSerialized() throws IOException {
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(new FolderSerializerWithInternalObjectMapper());
|
||||
mapper.registerModule(module);
|
||||
|
||||
String json = mapper.writeValueAsString(mockFolder);
|
||||
|
||||
HashMap<String, Object> actual = mapper.readValue(json, mapType);
|
||||
|
||||
assertTrue(actual.containsKey("name"));
|
||||
assertTrue(actual.containsKey("files"));
|
||||
assertEquals(mockFolder.getName(), actual.get("name"));
|
||||
|
||||
List actualFiles = (List) actual.get("files");
|
||||
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = StackOverflowError.class)
|
||||
public void givenFolder_whenSerializedWithCallingOwnSerializer_exceptionOccured() throws IOException {
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(new FolderSerializerWithCallingOwnSerializer());
|
||||
mapper.registerModule(module);
|
||||
|
||||
mapper.writeValueAsString(mockFolder);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFolder_whenSerializedWithDefaultSerializerStored_NameAndFilesAndDetailsFieldsSerialized() throws IOException {
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.setSerializerModifier(new FolderBeanSerializerModifier());
|
||||
mapper.registerModule(module);
|
||||
|
||||
String json = mapper.writeValueAsString(mockFolder);
|
||||
|
||||
HashMap<String, Object> actual = mapper.readValue(json, mapType);
|
||||
|
||||
assertTrue(actual.containsKey("name"));
|
||||
assertTrue(actual.containsKey("files"));
|
||||
assertEquals(mockFolder.getName(), actual.get("name"));
|
||||
|
||||
List actualFiles = (List) actual.get("files");
|
||||
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
|
||||
|
||||
Map actualDetails = (Map) actual.get("details");
|
||||
assertTrue(actualDetails.containsKey("id"));
|
||||
assertTrue(actualDetails.containsKey("name"));
|
||||
assertTrue(actualDetails.containsKey("owner"));
|
||||
assertTrue(actualDetails.containsKey("created"));
|
||||
assertTrue(actualDetails.containsKey("modified"));
|
||||
assertTrue(actualDetails.containsKey("lastAccess"));
|
||||
|
||||
assertEquals(mockFolder.getId().longValue(), ((Number)actualDetails.get("id")).longValue());
|
||||
assertEquals(mockFolder.getName(), actualDetails.get("name"));
|
||||
assertEquals(mockFolder.getOwner(), actualDetails.get("owner"));
|
||||
assertEquals(mockFolder.getCreated(), new Date((long) actualDetails.get("created")));
|
||||
assertEquals(mockFolder.getModified(), new Date((long) actualDetails.get("modified")));
|
||||
assertEquals(mockFolder.getLastAccess(), new Date((long) actualDetails.get("lastAccess")));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.deserialization;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class CustomDeserializationUnitTest {
|
||||
|
||||
@Test
|
||||
public final void whenDeserializingTheStandardRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException {
|
||||
final String json = "{\"id\":1,\"itemName\":\"theItem\",\"owner\":{\"id\":2,\"name\":\"theUser\"}}";
|
||||
|
||||
final Item readValue = new ObjectMapper().readValue(json, Item.class);
|
||||
assertThat(readValue, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenDeserializingANonStandardRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException {
|
||||
final String json = "{\"id\":1,\"itemName\":\"theItem\",\"createdBy\":2}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
final SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(Item.class, new ItemDeserializer());
|
||||
mapper.registerModule(module);
|
||||
|
||||
final Item readValue = mapper.readValue(json, Item.class);
|
||||
assertThat(readValue, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenDeserializerIsOnClass_whenDeserializingCustomRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException {
|
||||
final String json = "{\"id\":1,\"itemName\":\"theItem\",\"owner\":2}";
|
||||
|
||||
final ItemWithDeserializer readValue = new ObjectMapper().readValue(json, ItemWithDeserializer.class);
|
||||
assertThat(readValue, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserialisingZonedDateTimeWithDefaults_thenTimeZoneIsNotPreserved() throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.findAndRegisterModules();
|
||||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
// construct a new instance of ZonedDateTime
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
|
||||
String converted = objectMapper.writeValueAsString(now);
|
||||
// restore an instance of ZonedDateTime from String
|
||||
ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
|
||||
assertThat(now, is(not(restored)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserialisingZonedDateTimeWithFeaturesDisabled_thenTimeZoneIsPreserved() throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.findAndRegisterModules();
|
||||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
objectMapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);
|
||||
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
|
||||
// construct a new instance of ZonedDateTime
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
|
||||
String converted = objectMapper.writeValueAsString(now);
|
||||
// restore an instance of ZonedDateTime from String
|
||||
ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
|
||||
assertThat(restored, is(now));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.serialization;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class CustomSerializationUnitTest {
|
||||
|
||||
@Test
|
||||
public final void whenSerializing_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException {
|
||||
final Item myItem = new Item(1, "theItem", new User(2, "theUser"));
|
||||
final String serialized = new ObjectMapper().writeValueAsString(myItem);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenSerializingWithCustomSerializer_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException {
|
||||
final Item myItem = new Item(1, "theItem", new User(2, "theUser"));
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
final SimpleModule simpleModule = new SimpleModule();
|
||||
simpleModule.addSerializer(Item.class, new ItemSerializer());
|
||||
mapper.registerModule(simpleModule);
|
||||
|
||||
final String serialized = mapper.writeValueAsString(myItem);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenSerializerRegisteredOnClass_whenSerializingWithCustomSerializer_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException {
|
||||
final ItemWithSerializer myItem = new ItemWithSerializer(1, "theItem", new User(2, "theUser"));
|
||||
|
||||
final String serialized = new ObjectMapper().writeValueAsString(myItem);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
|
||||
import com.fasterxml.jackson.databind.ser.FilterProvider;
|
||||
import com.fasterxml.jackson.databind.ser.PropertyFilter;
|
||||
import com.fasterxml.jackson.databind.ser.PropertyWriter;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
|
||||
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class IgnoreFieldsWithFilterUnitTest {
|
||||
|
||||
@Test
|
||||
public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException {
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue");
|
||||
final FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
|
||||
|
||||
final MyDtoWithFilter dtoObject = new MyDtoWithFilter();
|
||||
dtoObject.setIntValue(12);
|
||||
|
||||
final String dtoAsString = mapper.writer(filters)
|
||||
.writeValueAsString(dtoObject);
|
||||
|
||||
assertThat(dtoAsString, not(containsString("intValue")));
|
||||
assertThat(dtoAsString, containsString("booleanValue"));
|
||||
assertThat(dtoAsString, containsString("stringValue"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenTypeHasFilterThatIgnoresNegativeInt_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException {
|
||||
final PropertyFilter theFilter = new SimpleBeanPropertyFilter() {
|
||||
@Override
|
||||
public final void serializeAsField(final Object pojo, final JsonGenerator jgen, final SerializerProvider provider, final PropertyWriter writer) throws Exception {
|
||||
if (include(writer)) {
|
||||
if (!writer.getName()
|
||||
.equals("intValue")) {
|
||||
writer.serializeAsField(pojo, jgen, provider);
|
||||
return;
|
||||
}
|
||||
|
||||
final int intValue = ((MyDtoWithFilter) pojo).getIntValue();
|
||||
if (intValue >= 0) {
|
||||
writer.serializeAsField(pojo, jgen, provider);
|
||||
}
|
||||
} else if (!jgen.canOmitFields()) { // since 2.3
|
||||
writer.serializeAsOmittedField(pojo, jgen, provider);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean include(final BeanPropertyWriter writer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean include(final PropertyWriter writer) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
|
||||
|
||||
final MyDtoWithFilter dtoObject = new MyDtoWithFilter();
|
||||
dtoObject.setIntValue(-1);
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final String dtoAsString = mapper.writer(filters)
|
||||
.writeValueAsString(dtoObject);
|
||||
|
||||
assertThat(dtoAsString, not(containsString("intValue")));
|
||||
assertThat(dtoAsString, containsString("booleanValue"));
|
||||
assertThat(dtoAsString, containsString("stringValue"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.baeldung.skipfields;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationConfig;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
|
||||
|
||||
public class JacksonDynamicIgnoreUnitTest {
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mapper.setSerializationInclusion(Include.NON_EMPTY);
|
||||
mapper.registerModule(new SimpleModule() {
|
||||
@Override
|
||||
public void setupModule(final SetupContext context) {
|
||||
super.setupModule(context);
|
||||
context.addBeanSerializerModifier(new BeanSerializerModifier() {
|
||||
@Override
|
||||
public JsonSerializer<?> modifySerializer(final SerializationConfig config, final BeanDescription beanDesc, final JsonSerializer<?> serializer) {
|
||||
if (Hidable.class.isAssignableFrom(beanDesc.getBeanClass())) {
|
||||
return new HidableSerializer((JsonSerializer<Object>) serializer);
|
||||
}
|
||||
return serializer;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNotHidden_thenCorrect() throws JsonProcessingException {
|
||||
final Address ad = new Address("ny", "usa", false);
|
||||
final Person person = new Person("john", ad, false);
|
||||
final String result = mapper.writeValueAsString(person);
|
||||
|
||||
assertTrue(result.contains("name"));
|
||||
assertTrue(result.contains("john"));
|
||||
assertTrue(result.contains("address"));
|
||||
assertTrue(result.contains("usa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddressHidden_thenCorrect() throws JsonProcessingException {
|
||||
final Address ad = new Address("ny", "usa", true);
|
||||
final Person person = new Person("john", ad, false);
|
||||
final String result = mapper.writeValueAsString(person);
|
||||
|
||||
assertTrue(result.contains("name"));
|
||||
assertTrue(result.contains("john"));
|
||||
assertFalse(result.contains("address"));
|
||||
assertFalse(result.contains("usa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAllHidden_thenCorrect() throws JsonProcessingException {
|
||||
final Address ad = new Address("ny", "usa", false);
|
||||
final Person person = new Person("john", ad, true);
|
||||
final String result = mapper.writeValueAsString(person);
|
||||
|
||||
assertTrue(result.length() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSerializeList_thenCorrect() throws JsonProcessingException {
|
||||
final Address ad1 = new Address("tokyo", "jp", true);
|
||||
final Address ad2 = new Address("london", "uk", false);
|
||||
final Address ad3 = new Address("ny", "usa", false);
|
||||
final Person p1 = new Person("john", ad1, false);
|
||||
final Person p2 = new Person("tom", ad2, true);
|
||||
final Person p3 = new Person("adam", ad3, false);
|
||||
|
||||
final String result = mapper.writeValueAsString(Arrays.asList(p1, p2, p3));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
## Jackson Exceptions
|
||||
|
||||
This module contains articles about Jackson exceptions.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Jackson Exceptions – Problems and Solutions](https://www.baeldung.com/jackson-exception)
|
||||
- [Jackson – JsonMappingException (No serializer found for class)](https://www.baeldung.com/jackson-jsonmappingexception)
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jackson-exceptions</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>jackson-exceptions</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.ossez</groupId>
|
||||
<artifactId>jackson-modules</artifactId>
|
||||
<version>0.0.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<finalName>jackson-exceptions</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
public class User {
|
||||
public int id;
|
||||
public String name;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public User(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
public class UserWithConflict {
|
||||
public int id;
|
||||
public String name;
|
||||
boolean checked;
|
||||
|
||||
public UserWithConflict() {
|
||||
super();
|
||||
}
|
||||
|
||||
public UserWithConflict(final int id, final String name, final boolean checked) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public boolean getChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
public class UserWithNoDefaultConstructor {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
public UserWithNoDefaultConstructor(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
public class UserWithPrivateFields {
|
||||
int id;
|
||||
String name;
|
||||
|
||||
public UserWithPrivateFields() {
|
||||
super();
|
||||
}
|
||||
|
||||
public UserWithPrivateFields(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
|
||||
@JsonRootName(value = "user")
|
||||
public class UserWithRoot {
|
||||
public int id;
|
||||
public String name;
|
||||
|
||||
public UserWithRoot() {
|
||||
super();
|
||||
}
|
||||
|
||||
public UserWithRoot(final int id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
public class Zoo {
|
||||
public Animal animal;
|
||||
|
||||
public Zoo() {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Animal {
|
||||
public String name;
|
||||
|
||||
public Animal() {
|
||||
}
|
||||
}
|
||||
|
||||
class Cat extends Animal {
|
||||
public int lives;
|
||||
|
||||
public Cat() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
||||
public class ZooConfigured {
|
||||
public AnimalConfigured animal;
|
||||
|
||||
public ZooConfigured() {
|
||||
}
|
||||
}
|
||||
|
||||
@JsonDeserialize(as = CatConfigured.class)
|
||||
abstract class AnimalConfigured {
|
||||
public String name;
|
||||
|
||||
public AnimalConfigured() {
|
||||
}
|
||||
}
|
||||
|
||||
class CatConfigured extends AnimalConfigured {
|
||||
public int lives;
|
||||
|
||||
public CatConfigured() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.mappingexception;
|
||||
|
||||
public class MyDtoNoAccessors {
|
||||
|
||||
String stringValue;
|
||||
int intValue;
|
||||
boolean booleanValue;
|
||||
|
||||
public MyDtoNoAccessors() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyDtoNoAccessors(final String stringValue, final int intValue, final boolean booleanValue) {
|
||||
super();
|
||||
|
||||
this.stringValue = stringValue;
|
||||
this.intValue = intValue;
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.mappingexception;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
|
||||
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
|
||||
public class MyDtoNoAccessorsAndFieldVisibility {
|
||||
|
||||
String stringValue;
|
||||
int intValue;
|
||||
boolean booleanValue;
|
||||
|
||||
public MyDtoNoAccessorsAndFieldVisibility() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyDtoNoAccessorsAndFieldVisibility(final String stringValue, final int intValue, final boolean booleanValue) {
|
||||
super();
|
||||
|
||||
this.stringValue = stringValue;
|
||||
this.intValue = intValue;
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
package com.baeldung.exceptions;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.exceptions.User;
|
||||
import com.baeldung.exceptions.UserWithPrivateFields;
|
||||
import com.baeldung.exceptions.UserWithRoot;
|
||||
import com.baeldung.exceptions.Zoo;
|
||||
import com.baeldung.exceptions.ZooConfigured;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
|
||||
|
||||
public class JacksonExceptionsUnitTest {
|
||||
|
||||
// JsonMappingException: Can not construct instance of
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public void givenAbstractClass_whenDeserializing_thenException() throws IOException {
|
||||
final String json = "{\"animal\":{\"name\":\"lacy\"}}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.reader()
|
||||
.forType(Zoo.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAbstractClassConfigured_whenDeserializing_thenCorrect() throws IOException {
|
||||
final String json = "{\"animal\":{\"name\":\"lacy\"}}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.reader()
|
||||
.forType(ZooConfigured.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
// JsonMappingException: No serializer found for class
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public void givenClassWithPrivateFields_whenSerializing_thenException() throws IOException {
|
||||
final UserWithPrivateFields user = new UserWithPrivateFields(1, "John");
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.writer()
|
||||
.writeValueAsString(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenClassWithPrivateFields_whenConfigureSerializing_thenCorrect() throws IOException {
|
||||
final UserWithPrivateFields user = new UserWithPrivateFields(1, "John");
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
|
||||
|
||||
final String result = mapper.writer()
|
||||
.writeValueAsString(user);
|
||||
assertThat(result, containsString("John"));
|
||||
}
|
||||
|
||||
// JsonMappingException: No suitable constructor found
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public void givenNoDefaultConstructor_whenDeserializing_thenException() throws IOException {
|
||||
final String json = "{\"id\":1,\"name\":\"John\"}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.reader()
|
||||
.forType(UserWithNoDefaultConstructor.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDefaultConstructor_whenDeserializing_thenCorrect() throws IOException {
|
||||
final String json = "{\"id\":1,\"name\":\"John\"}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
final User user = mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
assertEquals("John", user.name);
|
||||
}
|
||||
|
||||
// JsonMappingException: Root name does not match expected
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public void givenWrappedJsonString_whenDeserializing_thenException() throws IOException {
|
||||
final String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}";
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
|
||||
|
||||
mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWrappedJsonStringAndConfigureClass_whenDeserializing_thenCorrect() throws IOException {
|
||||
final String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}";
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
|
||||
|
||||
final UserWithRoot user = mapper.reader()
|
||||
.forType(UserWithRoot.class)
|
||||
.readValue(json);
|
||||
assertEquals("John", user.name);
|
||||
}
|
||||
|
||||
// JsonMappingException: Can not deserialize instance of
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public void givenJsonOfArray_whenDeserializing_thenException() throws JsonProcessingException, IOException {
|
||||
final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJsonOfArray_whenDeserializing_thenCorrect() throws JsonProcessingException, IOException {
|
||||
final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
final List<User> users = mapper.reader()
|
||||
.forType(new TypeReference<List<User>>() {
|
||||
})
|
||||
.readValue(json);
|
||||
|
||||
assertEquals(2, users.size());
|
||||
}
|
||||
|
||||
// UnrecognizedPropertyException
|
||||
@Test(expected = UnrecognizedPropertyException.class)
|
||||
public void givenJsonStringWithExtra_whenDeserializing_thenException() throws IOException {
|
||||
final String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}";
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJsonStringWithExtra_whenConfigureDeserializing_thenCorrect() throws IOException {
|
||||
final String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}";
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
|
||||
final User user = mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
assertEquals("John", user.name);
|
||||
}
|
||||
|
||||
// JsonParseException: Unexpected character (''' (code 39))
|
||||
@Test(expected = JsonParseException.class)
|
||||
public void givenStringWithSingleQuotes_whenDeserializing_thenException() throws JsonProcessingException, IOException {
|
||||
final String json = "{'id':1,'name':'John'}";
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringWithSingleQuotes_whenConfigureDeserializing_thenCorrect() throws JsonProcessingException, IOException {
|
||||
final String json = "{'id':1,'name':'John'}";
|
||||
|
||||
final JsonFactory factory = new JsonFactory();
|
||||
factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
|
||||
final ObjectMapper mapper = new ObjectMapper(factory);
|
||||
|
||||
final User user = mapper.reader()
|
||||
.forType(User.class)
|
||||
.readValue(json);
|
||||
assertEquals("John", user.name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.mappingexception;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class JacksonMappingExceptionUnitTest {
|
||||
|
||||
@Test(expected = JsonMappingException.class)
|
||||
public final void givenObjectHasNoAccessors_whenSerializing_thenException() throws JsonParseException, IOException {
|
||||
final String dtoAsString = new ObjectMapper().writeValueAsString(new MyDtoNoAccessors());
|
||||
|
||||
assertThat(dtoAsString, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenObjectHasNoAccessors_whenSerializingWithPrivateFieldsVisibility_thenNoException() throws JsonParseException, IOException {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
|
||||
final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessors());
|
||||
|
||||
assertThat(dtoAsString, containsString("intValue"));
|
||||
assertThat(dtoAsString, containsString("stringValue"));
|
||||
assertThat(dtoAsString, containsString("booleanValue"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException() throws JsonParseException, IOException {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessorsAndFieldVisibility());
|
||||
|
||||
assertThat(dtoAsString, containsString("intValue"));
|
||||
assertThat(dtoAsString, containsString("stringValue"));
|
||||
assertThat(dtoAsString, containsString("booleanValue"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jackson-modules</artifactId>
|
||||
<name>jackson-modules</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.ossez</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.2-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>jackson</module>
|
||||
<module>jackson-annotations</module>
|
||||
<module>jackson-conversions</module>
|
||||
<module>jackson-conversions-2</module>
|
||||
<module>jackson-custom-conversions</module>
|
||||
<module>jackson-exceptions</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<!--jackson for xml -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue