How to serialize/deserialize a DefaultMutableTreeNode with Jackson?2019 Community Moderator ElectionHow to serialize DefaultMutableTreeNode (Java) to JSON?Why do i get an stackoverflow error when using jackson even though using @JsonIgnorePropertiesSerializing to JSON in jQueryHow do I read / convert an InputStream into a String in Java?How can I pretty-print JSON in a shell script?How do I test for an empty JavaScript object?Deserialize JSON into C# dynamic object?Ignoring new fields on JSON objects using JacksonHow to use Jackson to deserialise an array of objectshow to specify jackson to only use fields - preferably globallyHow to tell Jackson to ignore a field during serialization if its value is null?Can Jackson deserialize into Map<Long, String> with just annotations?
Do the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?
ERC721: How to get the owned tokens of an address
Brexit - No Deal Rejection
Why does overlay work only on the first tcolorbox?
What did “the good wine” (τὸν καλὸν οἶνον) mean in John 2:10?
How to pronounce "I ♥ Huckabees"?
Shortcut for setting origin to vertex
Why does a Star of David appear at a rally with Francisco Franco?
What is a ^ b and (a & b) << 1?
et qui - how do you really understand that kind of phraseology?
Recruiter wants very extensive technical details about all of my previous work
A single argument pattern definition applies to multiple-argument patterns?
Math equation in non italic font
What is the Japanese sound word for the clinking of money?
What is "focus distance lower/upper" and how is it different from depth of field?
Are all passive ability checks floors for active ability checks?
Is it normal that my co-workers at a fitness company criticize my food choices?
Have the tides ever turned twice on any open problem?
Simplify an interface for flexibly applying rules to periods of time
Why did it take so long to abandon sail after steamships were demonstrated?
Did Ender ever learn that he killed Stilson and/or Bonzo?
Time travel from stationary position?
Instead of a Universal Basic Income program, why not implement a "Universal Basic Needs" program?
Is there a symmetric-key algorithm which we can use for creating a signature?
How to serialize/deserialize a DefaultMutableTreeNode with Jackson?
2019 Community Moderator ElectionHow to serialize DefaultMutableTreeNode (Java) to JSON?Why do i get an stackoverflow error when using jackson even though using @JsonIgnorePropertiesSerializing to JSON in jQueryHow do I read / convert an InputStream into a String in Java?How can I pretty-print JSON in a shell script?How do I test for an empty JavaScript object?Deserialize JSON into C# dynamic object?Ignoring new fields on JSON objects using JacksonHow to use Jackson to deserialise an array of objectshow to specify jackson to only use fields - preferably globallyHow to tell Jackson to ignore a field during serialization if its value is null?Can Jackson deserialize into Map<Long, String> with just annotations?
How can we serialize/deserialize Swing's DefaultMutableTreeNode to/from JSON with Jackson?
There is a related question
How to serialize DefaultMutableTreeNode (Java) to JSON?.
But it asked for Gson, not Jackson (and only
for serialization, not for deserialization).
For DefaultMutableTreeNode Jackson's default
serialization/serialization doesn't work, for various reasons:
- It contains children which again are
DefaultMutableTreeNodeobjects.
But it doesn't have the canonical getter and setter methods for that
(likegetChildren()andsetChildren(...)). - It contains back-references (via methods
getParent(),getRoot(),getPath()) which would lead to infinite recursion and StackOverflow
during serialization. - It has many redundant getter methods (like
isLeaf(),getNextSibling(),getLastChild(), ...) which don't need
to be serialized, because they are derived from other properties.
java json recursion serialization jackson
add a comment |
How can we serialize/deserialize Swing's DefaultMutableTreeNode to/from JSON with Jackson?
There is a related question
How to serialize DefaultMutableTreeNode (Java) to JSON?.
But it asked for Gson, not Jackson (and only
for serialization, not for deserialization).
For DefaultMutableTreeNode Jackson's default
serialization/serialization doesn't work, for various reasons:
- It contains children which again are
DefaultMutableTreeNodeobjects.
But it doesn't have the canonical getter and setter methods for that
(likegetChildren()andsetChildren(...)). - It contains back-references (via methods
getParent(),getRoot(),getPath()) which would lead to infinite recursion and StackOverflow
during serialization. - It has many redundant getter methods (like
isLeaf(),getNextSibling(),getLastChild(), ...) which don't need
to be serialized, because they are derived from other properties.
java json recursion serialization jackson
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There isMixInfeature is used to disable cycles.
– Michał Ziober
Mar 6 at 22:18
add a comment |
How can we serialize/deserialize Swing's DefaultMutableTreeNode to/from JSON with Jackson?
There is a related question
How to serialize DefaultMutableTreeNode (Java) to JSON?.
But it asked for Gson, not Jackson (and only
for serialization, not for deserialization).
For DefaultMutableTreeNode Jackson's default
serialization/serialization doesn't work, for various reasons:
- It contains children which again are
DefaultMutableTreeNodeobjects.
But it doesn't have the canonical getter and setter methods for that
(likegetChildren()andsetChildren(...)). - It contains back-references (via methods
getParent(),getRoot(),getPath()) which would lead to infinite recursion and StackOverflow
during serialization. - It has many redundant getter methods (like
isLeaf(),getNextSibling(),getLastChild(), ...) which don't need
to be serialized, because they are derived from other properties.
java json recursion serialization jackson
How can we serialize/deserialize Swing's DefaultMutableTreeNode to/from JSON with Jackson?
There is a related question
How to serialize DefaultMutableTreeNode (Java) to JSON?.
But it asked for Gson, not Jackson (and only
for serialization, not for deserialization).
For DefaultMutableTreeNode Jackson's default
serialization/serialization doesn't work, for various reasons:
- It contains children which again are
DefaultMutableTreeNodeobjects.
But it doesn't have the canonical getter and setter methods for that
(likegetChildren()andsetChildren(...)). - It contains back-references (via methods
getParent(),getRoot(),getPath()) which would lead to infinite recursion and StackOverflow
during serialization. - It has many redundant getter methods (like
isLeaf(),getNextSibling(),getLastChild(), ...) which don't need
to be serialized, because they are derived from other properties.
java json recursion serialization jackson
java json recursion serialization jackson
edited Mar 9 at 19:49
Thomas Fritsch
asked Mar 6 at 20:39
Thomas FritschThomas Fritsch
5,466122235
5,466122235
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There isMixInfeature is used to disable cycles.
– Michał Ziober
Mar 6 at 22:18
add a comment |
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There isMixInfeature is used to disable cycles.
– Michał Ziober
Mar 6 at 22:18
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There is
MixIn feature is used to disable cycles.– Michał Ziober
Mar 6 at 22:18
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There is
MixIn feature is used to disable cycles.– Michał Ziober
Mar 6 at 22:18
add a comment |
1 Answer
1
active
oldest
votes
You can to customize Jackson's ObjectMapper with aJsonSerializer and JsonDeserializer specially
crafted for converting a DefaultMutableTreeNode to JSON
and vice versa.
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new SimpleModule()
.addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))
.enable(SerializationFeature.INDENT_OUTPUT);
The DefaultMutableTreeNodeSerializer below is responsible
for converting a DefaultMutableTreeNode to JSON.
It writes the allowsChildren, userObject and children
of DefaultMutableTreeNode to JSON.
It does not write its parent, because that would
lead to infinite recursion and StackOverflowError.
Instead, the parent-child relations are encoded in the nested
structure of the JSON-output.
public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode>
@Override
public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)
throws IOException
gen.writeStartObject();
gen.writeBooleanField("allowsChildren", node.getAllowsChildren());
gen.writeObjectField("userObject", node.getUserObject());
if (node.getChildCount() > 0)
gen.writeObjectField("children", Collections.list(node.children()));
// Don't write node.getParent(), it would lead to infinite recursion.
gen.writeEndObject();
For testing you can serialize the root node of a sample JTree,
and then deserialize it again.

JTree tree = new JTree(); // a sample tree
Object root = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String json = objectMapper.writeValueAsString(root);
System.out.println(json);
DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);
It generates the following JSON output:
"allowsChildren" : true,
"userObject" : "JTree",
"children" : [
"allowsChildren" : true,
"userObject" : "colors",
"children" : [
"allowsChildren" : true,
"userObject" : "blue"
,
"allowsChildren" : true,
"userObject" : "violet"
,
"allowsChildren" : true,
"userObject" : "red"
,
"allowsChildren" : true,
"userObject" : "yellow"
]
,
"allowsChildren" : true,
"userObject" : "sports",
"children" : [
"allowsChildren" : true,
"userObject" : "basketball"
,
"allowsChildren" : true,
"userObject" : "soccer"
,
"allowsChildren" : true,
"userObject" : "football"
,
"allowsChildren" : true,
"userObject" : "hockey"
]
,
"allowsChildren" : true,
"userObject" : "food",
"children" : [
"allowsChildren" : true,
"userObject" : "hot dogs"
,
"allowsChildren" : true,
"userObject" : "pizza"
,
"allowsChildren" : true,
"userObject" : "ravioli"
,
"allowsChildren" : true,
"userObject" : "bananas"
]
]
The DefaultMutableTreeNodeDeserializer below is
responsible for converting JSON back to a DefaultMutableTreeNode.
The DefaultMutableTreeNode is very not POJO-like
and thus doesn't work well together with Jackson.
Therefore I created a well-behaving POJO helper class
(with properties allowsChildren, userObject
and children)
and let Jackson deserialize the JSON content into this class.
Then I convert the POJO object (and its POJO
children) to a DefaultMutableTreeNode object
(with DefaultMutableTreeNode children).
public class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode>
@Override
public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)
throws IOException
return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();
private static class POJO
private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent
public DefaultMutableTreeNode toDefaultMutableTreeNode()
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null)
for (POJO child : children)
node.add(child.toDefaultMutableTreeNode()); // recursion
// this did also set the parent of the child-node
return node;
// Following setters needed by Jackson's deserialization:
public void setAllowsChildren(boolean allowsChildren)
this.allowsChildren = allowsChildren;
public void setUserObject(Object userObject)
this.userObject = userObject;
public void setChildren(List<POJO> children)
this.children = children;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55031797%2fhow-to-serialize-deserialize-a-defaultmutabletreenode-with-jackson%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can to customize Jackson's ObjectMapper with aJsonSerializer and JsonDeserializer specially
crafted for converting a DefaultMutableTreeNode to JSON
and vice versa.
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new SimpleModule()
.addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))
.enable(SerializationFeature.INDENT_OUTPUT);
The DefaultMutableTreeNodeSerializer below is responsible
for converting a DefaultMutableTreeNode to JSON.
It writes the allowsChildren, userObject and children
of DefaultMutableTreeNode to JSON.
It does not write its parent, because that would
lead to infinite recursion and StackOverflowError.
Instead, the parent-child relations are encoded in the nested
structure of the JSON-output.
public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode>
@Override
public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)
throws IOException
gen.writeStartObject();
gen.writeBooleanField("allowsChildren", node.getAllowsChildren());
gen.writeObjectField("userObject", node.getUserObject());
if (node.getChildCount() > 0)
gen.writeObjectField("children", Collections.list(node.children()));
// Don't write node.getParent(), it would lead to infinite recursion.
gen.writeEndObject();
For testing you can serialize the root node of a sample JTree,
and then deserialize it again.

JTree tree = new JTree(); // a sample tree
Object root = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String json = objectMapper.writeValueAsString(root);
System.out.println(json);
DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);
It generates the following JSON output:
"allowsChildren" : true,
"userObject" : "JTree",
"children" : [
"allowsChildren" : true,
"userObject" : "colors",
"children" : [
"allowsChildren" : true,
"userObject" : "blue"
,
"allowsChildren" : true,
"userObject" : "violet"
,
"allowsChildren" : true,
"userObject" : "red"
,
"allowsChildren" : true,
"userObject" : "yellow"
]
,
"allowsChildren" : true,
"userObject" : "sports",
"children" : [
"allowsChildren" : true,
"userObject" : "basketball"
,
"allowsChildren" : true,
"userObject" : "soccer"
,
"allowsChildren" : true,
"userObject" : "football"
,
"allowsChildren" : true,
"userObject" : "hockey"
]
,
"allowsChildren" : true,
"userObject" : "food",
"children" : [
"allowsChildren" : true,
"userObject" : "hot dogs"
,
"allowsChildren" : true,
"userObject" : "pizza"
,
"allowsChildren" : true,
"userObject" : "ravioli"
,
"allowsChildren" : true,
"userObject" : "bananas"
]
]
The DefaultMutableTreeNodeDeserializer below is
responsible for converting JSON back to a DefaultMutableTreeNode.
The DefaultMutableTreeNode is very not POJO-like
and thus doesn't work well together with Jackson.
Therefore I created a well-behaving POJO helper class
(with properties allowsChildren, userObject
and children)
and let Jackson deserialize the JSON content into this class.
Then I convert the POJO object (and its POJO
children) to a DefaultMutableTreeNode object
(with DefaultMutableTreeNode children).
public class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode>
@Override
public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)
throws IOException
return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();
private static class POJO
private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent
public DefaultMutableTreeNode toDefaultMutableTreeNode()
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null)
for (POJO child : children)
node.add(child.toDefaultMutableTreeNode()); // recursion
// this did also set the parent of the child-node
return node;
// Following setters needed by Jackson's deserialization:
public void setAllowsChildren(boolean allowsChildren)
this.allowsChildren = allowsChildren;
public void setUserObject(Object userObject)
this.userObject = userObject;
public void setChildren(List<POJO> children)
this.children = children;
add a comment |
You can to customize Jackson's ObjectMapper with aJsonSerializer and JsonDeserializer specially
crafted for converting a DefaultMutableTreeNode to JSON
and vice versa.
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new SimpleModule()
.addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))
.enable(SerializationFeature.INDENT_OUTPUT);
The DefaultMutableTreeNodeSerializer below is responsible
for converting a DefaultMutableTreeNode to JSON.
It writes the allowsChildren, userObject and children
of DefaultMutableTreeNode to JSON.
It does not write its parent, because that would
lead to infinite recursion and StackOverflowError.
Instead, the parent-child relations are encoded in the nested
structure of the JSON-output.
public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode>
@Override
public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)
throws IOException
gen.writeStartObject();
gen.writeBooleanField("allowsChildren", node.getAllowsChildren());
gen.writeObjectField("userObject", node.getUserObject());
if (node.getChildCount() > 0)
gen.writeObjectField("children", Collections.list(node.children()));
// Don't write node.getParent(), it would lead to infinite recursion.
gen.writeEndObject();
For testing you can serialize the root node of a sample JTree,
and then deserialize it again.

JTree tree = new JTree(); // a sample tree
Object root = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String json = objectMapper.writeValueAsString(root);
System.out.println(json);
DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);
It generates the following JSON output:
"allowsChildren" : true,
"userObject" : "JTree",
"children" : [
"allowsChildren" : true,
"userObject" : "colors",
"children" : [
"allowsChildren" : true,
"userObject" : "blue"
,
"allowsChildren" : true,
"userObject" : "violet"
,
"allowsChildren" : true,
"userObject" : "red"
,
"allowsChildren" : true,
"userObject" : "yellow"
]
,
"allowsChildren" : true,
"userObject" : "sports",
"children" : [
"allowsChildren" : true,
"userObject" : "basketball"
,
"allowsChildren" : true,
"userObject" : "soccer"
,
"allowsChildren" : true,
"userObject" : "football"
,
"allowsChildren" : true,
"userObject" : "hockey"
]
,
"allowsChildren" : true,
"userObject" : "food",
"children" : [
"allowsChildren" : true,
"userObject" : "hot dogs"
,
"allowsChildren" : true,
"userObject" : "pizza"
,
"allowsChildren" : true,
"userObject" : "ravioli"
,
"allowsChildren" : true,
"userObject" : "bananas"
]
]
The DefaultMutableTreeNodeDeserializer below is
responsible for converting JSON back to a DefaultMutableTreeNode.
The DefaultMutableTreeNode is very not POJO-like
and thus doesn't work well together with Jackson.
Therefore I created a well-behaving POJO helper class
(with properties allowsChildren, userObject
and children)
and let Jackson deserialize the JSON content into this class.
Then I convert the POJO object (and its POJO
children) to a DefaultMutableTreeNode object
(with DefaultMutableTreeNode children).
public class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode>
@Override
public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)
throws IOException
return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();
private static class POJO
private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent
public DefaultMutableTreeNode toDefaultMutableTreeNode()
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null)
for (POJO child : children)
node.add(child.toDefaultMutableTreeNode()); // recursion
// this did also set the parent of the child-node
return node;
// Following setters needed by Jackson's deserialization:
public void setAllowsChildren(boolean allowsChildren)
this.allowsChildren = allowsChildren;
public void setUserObject(Object userObject)
this.userObject = userObject;
public void setChildren(List<POJO> children)
this.children = children;
add a comment |
You can to customize Jackson's ObjectMapper with aJsonSerializer and JsonDeserializer specially
crafted for converting a DefaultMutableTreeNode to JSON
and vice versa.
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new SimpleModule()
.addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))
.enable(SerializationFeature.INDENT_OUTPUT);
The DefaultMutableTreeNodeSerializer below is responsible
for converting a DefaultMutableTreeNode to JSON.
It writes the allowsChildren, userObject and children
of DefaultMutableTreeNode to JSON.
It does not write its parent, because that would
lead to infinite recursion and StackOverflowError.
Instead, the parent-child relations are encoded in the nested
structure of the JSON-output.
public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode>
@Override
public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)
throws IOException
gen.writeStartObject();
gen.writeBooleanField("allowsChildren", node.getAllowsChildren());
gen.writeObjectField("userObject", node.getUserObject());
if (node.getChildCount() > 0)
gen.writeObjectField("children", Collections.list(node.children()));
// Don't write node.getParent(), it would lead to infinite recursion.
gen.writeEndObject();
For testing you can serialize the root node of a sample JTree,
and then deserialize it again.

JTree tree = new JTree(); // a sample tree
Object root = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String json = objectMapper.writeValueAsString(root);
System.out.println(json);
DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);
It generates the following JSON output:
"allowsChildren" : true,
"userObject" : "JTree",
"children" : [
"allowsChildren" : true,
"userObject" : "colors",
"children" : [
"allowsChildren" : true,
"userObject" : "blue"
,
"allowsChildren" : true,
"userObject" : "violet"
,
"allowsChildren" : true,
"userObject" : "red"
,
"allowsChildren" : true,
"userObject" : "yellow"
]
,
"allowsChildren" : true,
"userObject" : "sports",
"children" : [
"allowsChildren" : true,
"userObject" : "basketball"
,
"allowsChildren" : true,
"userObject" : "soccer"
,
"allowsChildren" : true,
"userObject" : "football"
,
"allowsChildren" : true,
"userObject" : "hockey"
]
,
"allowsChildren" : true,
"userObject" : "food",
"children" : [
"allowsChildren" : true,
"userObject" : "hot dogs"
,
"allowsChildren" : true,
"userObject" : "pizza"
,
"allowsChildren" : true,
"userObject" : "ravioli"
,
"allowsChildren" : true,
"userObject" : "bananas"
]
]
The DefaultMutableTreeNodeDeserializer below is
responsible for converting JSON back to a DefaultMutableTreeNode.
The DefaultMutableTreeNode is very not POJO-like
and thus doesn't work well together with Jackson.
Therefore I created a well-behaving POJO helper class
(with properties allowsChildren, userObject
and children)
and let Jackson deserialize the JSON content into this class.
Then I convert the POJO object (and its POJO
children) to a DefaultMutableTreeNode object
(with DefaultMutableTreeNode children).
public class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode>
@Override
public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)
throws IOException
return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();
private static class POJO
private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent
public DefaultMutableTreeNode toDefaultMutableTreeNode()
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null)
for (POJO child : children)
node.add(child.toDefaultMutableTreeNode()); // recursion
// this did also set the parent of the child-node
return node;
// Following setters needed by Jackson's deserialization:
public void setAllowsChildren(boolean allowsChildren)
this.allowsChildren = allowsChildren;
public void setUserObject(Object userObject)
this.userObject = userObject;
public void setChildren(List<POJO> children)
this.children = children;
You can to customize Jackson's ObjectMapper with aJsonSerializer and JsonDeserializer specially
crafted for converting a DefaultMutableTreeNode to JSON
and vice versa.
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new SimpleModule()
.addSerializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeSerializer())
.addDeserializer(DefaultMutableTreeNode.class, new DefaultMutableTreeNodeDeserializer()))
.enable(SerializationFeature.INDENT_OUTPUT);
The DefaultMutableTreeNodeSerializer below is responsible
for converting a DefaultMutableTreeNode to JSON.
It writes the allowsChildren, userObject and children
of DefaultMutableTreeNode to JSON.
It does not write its parent, because that would
lead to infinite recursion and StackOverflowError.
Instead, the parent-child relations are encoded in the nested
structure of the JSON-output.
public class DefaultMutableTreeNodeSerializer extends JsonSerializer<DefaultMutableTreeNode>
@Override
public void serialize(DefaultMutableTreeNode node, JsonGenerator gen, SerializerProvider serializers)
throws IOException
gen.writeStartObject();
gen.writeBooleanField("allowsChildren", node.getAllowsChildren());
gen.writeObjectField("userObject", node.getUserObject());
if (node.getChildCount() > 0)
gen.writeObjectField("children", Collections.list(node.children()));
// Don't write node.getParent(), it would lead to infinite recursion.
gen.writeEndObject();
For testing you can serialize the root node of a sample JTree,
and then deserialize it again.

JTree tree = new JTree(); // a sample tree
Object root = tree.getModel().getRoot(); // a DefaultMutableTreeNode
String json = objectMapper.writeValueAsString(root);
System.out.println(json);
DefaultMutableTreeNode root2 = objectMapper.readValue(json, DefaultMutableTreeNode.class);
It generates the following JSON output:
"allowsChildren" : true,
"userObject" : "JTree",
"children" : [
"allowsChildren" : true,
"userObject" : "colors",
"children" : [
"allowsChildren" : true,
"userObject" : "blue"
,
"allowsChildren" : true,
"userObject" : "violet"
,
"allowsChildren" : true,
"userObject" : "red"
,
"allowsChildren" : true,
"userObject" : "yellow"
]
,
"allowsChildren" : true,
"userObject" : "sports",
"children" : [
"allowsChildren" : true,
"userObject" : "basketball"
,
"allowsChildren" : true,
"userObject" : "soccer"
,
"allowsChildren" : true,
"userObject" : "football"
,
"allowsChildren" : true,
"userObject" : "hockey"
]
,
"allowsChildren" : true,
"userObject" : "food",
"children" : [
"allowsChildren" : true,
"userObject" : "hot dogs"
,
"allowsChildren" : true,
"userObject" : "pizza"
,
"allowsChildren" : true,
"userObject" : "ravioli"
,
"allowsChildren" : true,
"userObject" : "bananas"
]
]
The DefaultMutableTreeNodeDeserializer below is
responsible for converting JSON back to a DefaultMutableTreeNode.
The DefaultMutableTreeNode is very not POJO-like
and thus doesn't work well together with Jackson.
Therefore I created a well-behaving POJO helper class
(with properties allowsChildren, userObject
and children)
and let Jackson deserialize the JSON content into this class.
Then I convert the POJO object (and its POJO
children) to a DefaultMutableTreeNode object
(with DefaultMutableTreeNode children).
public class DefaultMutableTreeNodeDeserializer extends JsonDeserializer<DefaultMutableTreeNode>
@Override
public DefaultMutableTreeNode deserialize(JsonParser parser, DeserializationContext context)
throws IOException
return parser.readValueAs(POJO.class).toDefaultMutableTreeNode();
private static class POJO
private boolean allowsChildren;
private Object userObject;
private List<POJO> children;
// no need for: POJO parent
public DefaultMutableTreeNode toDefaultMutableTreeNode()
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.setAllowsChildren(allowsChildren);
node.setUserObject(userObject);
if (children != null)
for (POJO child : children)
node.add(child.toDefaultMutableTreeNode()); // recursion
// this did also set the parent of the child-node
return node;
// Following setters needed by Jackson's deserialization:
public void setAllowsChildren(boolean allowsChildren)
this.allowsChildren = allowsChildren;
public void setUserObject(Object userObject)
this.userObject = userObject;
public void setChildren(List<POJO> children)
this.children = children;
edited Mar 9 at 19:47
answered Mar 6 at 21:51
Thomas FritschThomas Fritsch
5,466122235
5,466122235
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55031797%2fhow-to-serialize-deserialize-a-defaultmutabletreenode-with-jackson%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Try to check also this question: Why do i get an stackoverflow error when using jackson even though using @JsonIgnoreProperties. There is
MixInfeature is used to disable cycles.– Michał Ziober
Mar 6 at 22:18