Add source code for article BAEL-2463 (#7543)
This commit is contained in:
parent
32127cc5b5
commit
9cb93861d9
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.jackson.entities;
|
||||
|
||||
public class File {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.baeldung.jackson.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
public class Folder {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String owner;
|
||||
|
||||
private Date created;
|
||||
|
||||
private Date modified;
|
||||
|
||||
private Date lastAccess;
|
||||
|
||||
@JsonIgnore
|
||||
private List<File> files = new ArrayList<>();
|
||||
|
||||
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 getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public Date getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(Date modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public Date getLastAccess() {
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
public void setLastAccess(Date lastAccess) {
|
||||
this.lastAccess = lastAccess;
|
||||
}
|
||||
|
||||
public List<File> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
public void setFiles(List<File> files) {
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializationConfig;
|
||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
|
||||
|
||||
public class FolderBeanSerializerModifier extends BeanSerializerModifier {
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
|
||||
|
||||
if (beanDesc.getBeanClass().equals(Folder.class)) {
|
||||
return new FolderSerializerWithDefaultSerializerStored((JsonSerializer<Object>) serializer);
|
||||
}
|
||||
|
||||
return serializer;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.File;
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class FolderSerializer extends StdSerializer<Folder> {
|
||||
|
||||
public FolderSerializer() {
|
||||
super(Folder.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("name", value.getName());
|
||||
|
||||
gen.writeArrayFieldStart("files");
|
||||
for (File file : value.getFiles()) {
|
||||
gen.writeStartObject();
|
||||
gen.writeNumberField("id", file.getId());
|
||||
gen.writeStringField("name", file.getName());
|
||||
gen.writeEndObject();
|
||||
}
|
||||
gen.writeEndArray();
|
||||
|
||||
gen.writeEndObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
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,35 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
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,34 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
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,29 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
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,166 @@
|
|||
package com.baeldung.jackson.serialization.custom.serializer;
|
||||
|
||||
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.baeldung.jackson.entities.File;
|
||||
import com.baeldung.jackson.entities.Folder;
|
||||
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")));
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue