Last active
August 29, 2015 13:56
-
-
Save theotherian/9285448 to your computer and use it in GitHub Desktop.
Using Jackson Mixins and Modules to fix serialization problems
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using Jackson Mixins and Modules to fix serialization problems |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private User createUser() { | |
User user = new User(); | |
user.setName("me"); | |
Thing thing = new Thing(); | |
thing.setName("that"); | |
thing.setUser(user); | |
user.setThings(Lists.newArrayList(thing)); | |
return user; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private Widget createWidget() { | |
Widget widget = new Widget(); | |
widget.setId(1); | |
WidgetName name = new WidgetName(); | |
name.value("my widget"); | |
widget.setName(name); | |
return widget; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson; | |
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.SerializationFeature; | |
import com.theotherian.jackson.dto.Widget; | |
import com.theotherian.jackson.dto.WidgetName; | |
public class ModuleTest { | |
@Test | |
public void failureWithoutProperty() throws Exception { | |
Widget widget = createWidget(); | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, widget); | |
System.out.println(writer.toString()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson; | |
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.Module; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.SerializationFeature; | |
import com.fasterxml.jackson.databind.module.SimpleModule; | |
import com.theotherian.jackson.dto.Widget; | |
import com.theotherian.jackson.dto.WidgetName; | |
import com.theotherian.jackson.serializer.WidgetNameSerializer; | |
public class ModuleSuccessTest { | |
@Test | |
public void success() throws Exception { | |
Widget widget = createWidget(); | |
ObjectMapper mapper = new ObjectMapper(); | |
Module serializerModule = new SimpleModule().addSerializer(WidgetName.class, new WidgetNameSerializer()); | |
mapper.registerModule(serializerModule); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, widget); | |
System.out.println(writer.toString()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson; | |
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.Module; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.SerializationFeature; | |
import com.fasterxml.jackson.databind.module.SimpleModule; | |
import com.theotherian.jackson.dto.Widget; | |
import com.theotherian.jackson.dto.WidgetName; | |
import com.theotherian.jackson.serializer.WidgetNameSerializer; | |
public class ModuleTest { | |
@Test | |
public void failureWithException() throws Exception { | |
Widget widget = createWidget(); | |
ObjectMapper mapper = new ObjectMapper(); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, widget); | |
System.out.println(writer.toString()); | |
} | |
@Test | |
public void failureWithoutProperty() throws Exception { | |
Widget widget = createWidget(); | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, widget); | |
System.out.println(writer.toString()); | |
} | |
@Test | |
public void success() throws Exception { | |
Widget widget = createWidget(); | |
ObjectMapper mapper = new ObjectMapper(); | |
Module serializerModule = new SimpleModule().addSerializer(WidgetName.class, new WidgetNameSerializer()); | |
mapper.registerModule(serializerModule); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, widget); | |
System.out.println(writer.toString()); | |
} | |
private Widget createWidget() { | |
Widget widget = new Widget(); | |
widget.setId(1); | |
WidgetName name = new WidgetName(); | |
name.value("my widget"); | |
widget.setName(name); | |
return widget; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> | |
<groupId>com.theotherian.jackson</groupId> | |
<artifactId>jackson-mixins-and-modules</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<packaging>jar</packaging> | |
<name>jackson-mixins-and-modules</name> | |
<url>http://maven.apache.org</url> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
</properties> | |
<build> | |
<plugins> | |
<plugin> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<configuration> | |
<source>1.7</source> | |
<target>1.7</target> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
<dependencies> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit-dep</artifactId> | |
<version>4.11</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>com.fasterxml.jackson.core</groupId> | |
<artifactId>jackson-core</artifactId> | |
<version>2.3.1</version> | |
</dependency> | |
<dependency> | |
<groupId>com.fasterxml.jackson.core</groupId> | |
<artifactId>jackson-annotations</artifactId> | |
<version>2.3.1</version> | |
</dependency> | |
<dependency> | |
<groupId>com.fasterxml.jackson.core</groupId> | |
<artifactId>jackson-databind</artifactId> | |
<version>2.3.1</version> | |
</dependency> | |
<dependency> | |
<groupId>com.google.guava</groupId> | |
<artifactId>guava</artifactId> | |
<version>16.0</version> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.theotherian.jackson.dto.User["things"]->java.util.ArrayList[0]->com.theotherian.jackson.dto.Thing["user"]->... | |
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:646) | |
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) | |
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541) | |
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:632) | |
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) | |
... | |
Caused by: java.lang.StackOverflowError | |
... | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.theotherian.jackson.dto.User; | |
public class SerializationFailureTest { | |
@Test | |
public void failure() throws Exception { | |
User user = createUser(); | |
ObjectMapper mapper = new ObjectMapper(); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, user); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson; | |
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.ser.FilterProvider; | |
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; | |
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; | |
import com.google.common.collect.Lists; | |
import com.theotherian.jackson.dto.Thing; | |
import com.theotherian.jackson.dto.User; | |
import com.theotherian.jackson.mixin.ThingMixin; | |
public class SerializationSuccessTest { | |
@Test | |
public void success() throws Exception { | |
User user = createUser(); | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.addMixInAnnotations(Thing.class, ThingMixin.class); | |
FilterProvider filterProvider = new SimpleFilterProvider() | |
.addFilter("thing filter", SimpleBeanPropertyFilter.serializeAllExcept("user")); | |
mapper.setFilters(filterProvider); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, user); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson; | |
import java.io.StringWriter; | |
import org.junit.Test; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.ser.FilterProvider; | |
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; | |
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; | |
import com.google.common.collect.Lists; | |
import com.theotherian.jackson.dto.Thing; | |
import com.theotherian.jackson.dto.User; | |
import com.theotherian.jackson.mixin.ThingMixin; | |
public class SerializationTest { | |
@Test | |
public void failure() throws Exception { | |
User user = createUser(); | |
ObjectMapper mapper = new ObjectMapper(); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, user); | |
} | |
@Test | |
public void success() throws Exception { | |
User user = createUser(); | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.addMixInAnnotations(Thing.class, ThingMixin.class); | |
FilterProvider filterProvider = new SimpleFilterProvider() | |
.addFilter("thing filter", SimpleBeanPropertyFilter.serializeAllExcept("user")); | |
mapper.setFilters(filterProvider); | |
StringWriter writer = new StringWriter(); | |
mapper.writeValue(writer, user); | |
} | |
private User createUser() { | |
User user = new User(); | |
user.setName("me"); | |
Thing thing = new Thing(); | |
thing.setName("that"); | |
thing.setUser(user); | |
user.setThings(Lists.newArrayList(thing)); | |
return user; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"id":1,"name":"my widget"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.dto; | |
public class Thing { | |
private String name; | |
public String getName() { return name; } | |
public void setName(String name) { this.name = name; } | |
private User user; | |
public User getUser() { return user; } | |
public void setUser(User user) { this.user = user; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.mixin; | |
import com.fasterxml.jackson.annotation.JsonFilter; | |
@JsonFilter("thing filter") | |
public class ThingMixin { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"id":1,"name":{}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.dto; | |
import java.util.List; | |
public class User { | |
private String name; | |
public String getName() { return name; } | |
public void setName(String name) { this.name = name; } | |
private List<Thing> things; | |
public List<Thing> getThings() { return things; } | |
public void setThings(List<Thing> things) { this.things = things; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.dto; | |
public class Widget { | |
private long id; | |
public long getId() { return id; } | |
public void setId(long id) { this.id = id; } | |
private WidgetName name; | |
public WidgetName getName() { return name; } | |
public void setName(WidgetName name) { this.name = name; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.dto; | |
public class WidgetName { | |
private String value; | |
public String value() { return value; } | |
public void value(String value) { this.value = value; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.theotherian.jackson.serializer; | |
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; | |
import com.theotherian.jackson.dto.WidgetName; | |
public class WidgetNameSerializer extends JsonSerializer<WidgetName> { | |
@Override | |
public void serialize(WidgetName widgetName, JsonGenerator jgen, SerializerProvider provider) throws IOException, | |
JsonProcessingException { | |
jgen.writeString(widgetName.value()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment