Option 1
Newer versions of JGraphT have built-in support for importing/exporting graphs from/to JSON using the jgrapht-io
module.
Here's an example for exporting a graph to JSON:
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.nio.json.JSONExporter;
import java.net.URI;
import java.net.URISyntaxException;
public class Main {
public static void main(String[] args) throws Exception {
final var jsonExporter = new JSONExporter<URI, DefaultEdge>();
jsonExporter.exportGraph(
newSampleGraph(),
System.out
);
System.out.println("");
}
// Copied from https://jgrapht.org/guide/HelloJGraphT
private static Graph<URI, DefaultEdge> newSampleGraph() throws URISyntaxException {
Graph<URI, DefaultEdge> g = new DefaultDirectedGraph<>(DefaultEdge.class);
URI google = new URI("http://www.google.com");
URI wikipedia = new URI("http://www.wikipedia.org");
URI jgrapht = new URI("http://www.jgrapht.org");
// add the vertices
g.addVertex(google);
g.addVertex(wikipedia);
g.addVertex(jgrapht);
// add edges to create linking structure
g.addEdge(jgrapht, wikipedia);
g.addEdge(google, jgrapht);
g.addEdge(google, wikipedia);
g.addEdge(wikipedia, google);
return g;
}
}
The pom.xml
file for reference:
<?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>
<groupId>com.stackoverflow</groupId>
<artifactId>questions-39438962</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-io</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
</project>
Option 2
Implement a custom Jackson serializer for JGraphT graphs, register it with an ObjectMapper
, and implement the logic in the serializer.
Here's an example:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.jgrapht.Graph;
import org.jgrapht.nio.IntegerIdProvider;
import java.io.IOException;
public class DefaultDirectedGraphSerializer<V, E, T extends Graph<V, E>> extends StdSerializer<T> {
public DefaultDirectedGraphSerializer(Class<T> t) {
super(t);
}
public DefaultDirectedGraphSerializer() {
this(null);
}
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException {
final var idProvider = new IntegerIdProvider<>();
gen.writeStartObject();
gen.writeFieldName("graph");
gen.writeStartObject();
gen.writeFieldName("nodes");
gen.writeStartObject();
for (V v : value.vertexSet()) {
final var id = idProvider.apply(v);
gen.writeFieldName(id);
gen.writeStartObject();
gen.writeStringField("label", v.toString());
gen.writeEndObject();
}
gen.writeEndObject();
gen.writeFieldName("edges");
gen.writeStartArray();
for (E e : value.edgeSet()) {
gen.writeStartObject();
final var source = value.getEdgeSource(e);
final var target = value.getEdgeTarget(e);
gen.writeStringField("source", idProvider.apply(source));
gen.writeStringField("target", idProvider.apply(target));
gen.writeEndObject();
}
gen.writeEndArray();
gen.writeEndObject();
gen.writeEndObject();
}
}
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;
import java.net.URI;
import java.net.URISyntaxException;
public class Graphs {
public static Graph<URI, DefaultEdge> newSampleGraph() throws URISyntaxException {
final var g = new DefaultDirectedGraph<URI, DefaultEdge>(DefaultEdge.class);
URI google = new URI("http://www.google.com");
URI wikipedia = new URI("http://www.wikipedia.org");
URI jgrapht = new URI("http://www.jgrapht.org");
g.addVertex(google);
g.addVertex(wikipedia);
g.addVertex(jgrapht);
g.addEdge(jgrapht, wikipedia);
g.addEdge(google, jgrapht);
g.addEdge(google, wikipedia);
g.addEdge(wikipedia, google);
return g;
}
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.jgrapht.graph.DefaultDirectedGraph;
import java.net.URISyntaxException;
import static org.example.Graphs.newSampleGraph;
public class Main {
public static void main(String[] args) throws URISyntaxException, JsonProcessingException {
final var module = new SimpleModule();
module.addSerializer(DefaultDirectedGraph.class, new DefaultDirectedGraphSerializer<>());
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.writeValueAsString(newSampleGraph()));
}
}
This will produce the following JSON document (after pretty printing):
{
"graph": {
"nodes": {
"1": {
"label": "http://www.google.com"
},
"2": {
"label": "http://www.wikipedia.org"
},
"3": {
"label": "http://www.jgrapht.org"
}
},
"edges": [
{
"source": "3",
"target": "2"
},
{
"source": "1",
"target": "3"
},
{
"source": "1",
"target": "2"
},
{
"source": "2",
"target": "1"
}
]
}
}