programing

jgrapht 심플 그래프를 json으로 시리얼화하려면 어떻게 해야 하나요?

muds 2023. 3. 7. 22:07
반응형

jgrapht 심플 그래프를 json으로 시리얼화하려면 어떻게 해야 하나요?

jgrapht에서 간단한 directed graph를 가지고 있으며, 다음과 같이 잭슨을 사용하여 JSON 파일로 연재하려고 합니다.

ObjectMapper mapper = new ObjectMapper();
File output = new File("P:\\tree.json");
ObjectWriter objectWriter = mapper.writer().withDefaultPrettyPrinter();
objectWriter.writeValue(output,simpleDirectedGraph);

다만, 다음의 에러가 표시됩니다.

스레드 "main"의 com.fasterxml.jackson.databind 예외가 있습니다.Json Mapping Exception:클래스 org.jgrapht.graph의 시리얼라이저를 찾을 수 없습니다.AbstractBaseGraph$ArrayListFactory이며 BeanSerializer를 생성하기 위해 검출된 속성이 없습니다(예외를 방지하려면 SerializationFeature를 비활성화하십시오).FAIL_ON_EMPTY_BENS) (레퍼런스 체인 org.jgrapht.graph 경유).com.fasterxml.jackson.databind.ser.impl의 SimpleDirectedGraph ["edgeSetFactory"])를 참조해 주세요.com.fasterxml.jackson.databind.ser.impl의 UnknownSerializer.failForEmpty(UnknownSerializer.java:69)입니다.com.fasterxml.jackson.databind.ser에서 UnknownSerializer.serialize(UnknownSerializer.java:32)를 지정합니다.Bean Property Writer.serializeAsField(BeanPropertyWriter.java:693)를 지정합니다.Bean Serializer Base 。연재하다com.fasterxml.jackson.databind.ser의 필드(BeanSerializerBase.java:675)입니다.com.fasterxml.jackson.databind.ser의 BeanSerializer.serialize(BeanSerializer.java:157)를 지정합니다.Default Serializer Provider 。serializeValue(DefaultSerializerProvider.java:130)를 지정합니다.com.fasterxml.jackson.databind에서 ObjectWriter$Prefetch.serialize(ObjectWriter.java:1387)를 지정합니다.오브젝트 라이터com.fasterxml.jackson.databind의 _configAndWriteValue(ObjectWriter.java:1088)입니다.오브젝트 라이터writeValue(ObjectWriter.java:909)를 지정합니다.sun.reflect의 JSONTreeGenerator.main(JSONTreeGenerator.java:45).Native Method Accessor Impl.sun.reflect에서 0(네이티브 메서드)을 호출합니다.Native Method Accessor Impl.sun.reflect에서 (NativeMethodAccessorImpl.java:62)를 호출합니다.Method Accessor Impl을 위임하고 있습니다.java.lang.reflect에서 (DelegatingMethodAccessorImpl.java:43)를 호출합니다.Method.invoke(Method.java:497).intellij.rt.displicate.application을 선택합니다.AppMain.main (AppMain.java:147)

GmlExporter가 있는 걸 봤는데 json에 관심이 많아서...내가 어떻게 그럴 수 있을까?

다음의 방법으로 예외를 디세블로 할 수 있습니다.

mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

잭슨에게서 받은 예외는 다음과 같습니다.

Json Mapping Exception:클래스 org.jgrapht.graph의 시리얼라이저를 찾을 수 없습니다.AbstractBaseGraph$ArrayListFactory이며 BeanSerializer를 생성하기 위해 검출된 속성이 없습니다(예외를 방지하려면 SerializationFeature를 비활성화하십시오).FAIL_ON_EMPTY_BENS) (레퍼런스 체인 org.jgrapht.graph 경유).com.fasterxml.jackson.databind.ser.impl의 SimpleDirectedGraph ["edgeSetFactory"])를 참조해 주세요.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)

는, 다음의 해결 방법에 대한 힌트를 제공합니다.

  • BeanSerializer를 생성하기 위해 검색된 속성이 없습니다.
  • SimpleDirectedGraph["edgeSetFactory"]텅 빈 것 같다

edgeSetFactory★★★★★★★★

AbstractBaseGraph$ArrayListFactory

커스텀 시리얼라이저 쓰기

잭슨은 'Jackson'을 합니다.StdBeanSerializerJSON을 사용하다안타깝게도 이것은 추상 수업에는 적용되지 않습니다.

여러분이 쓸 수 있어요.JsonSerializer특별한 분야를 다룰 수 있습니다.

그래프를 XML로 시리얼화한 후 XML에서 JSON으로 시리얼화할 수 있습니다.

XML로의 시리얼화 : 이 라이브러리를 사용할 수 있습니다.XStream http://x-stream.github.io은 XML과의 시리얼화 및 시리얼화 해제를 쉽게 할 수 있는 작은 라이브러리입니다.

라이브러리 사용 가이드:http://x-stream.github.io/tutorial.html

그 후 다음을 사용하여 XML을 JSON에 매핑합니다.

   <dependency>
   <groupId>org.json</groupId>
   <artifactId>json</artifactId>
   <version>20180813</version>
   </dependency>

XML.java는 다음과 같은 클래스입니다.

   import org.json.JSONObject;
   import org.json.XML;
   import org.json.JSONException;

   public class Main {

public static int PRETTY_PRINT_INDENT_FACTOR = 4;
public static String TEST_XML_STRING =
    "<?xml version=\"1.0\" ?><test attrib=\"moretest\">Turn this to JSON</test>";

public static void main(String[] args) {
    try {
        JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING);
        String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
        System.out.println(jsonPrettyPrintString);
    } catch (JSONException je) {
        System.out.println(je.toString());
           }
       }
   }

옵션 1

에서는, 「JGraphT」, 「JSON」의 「Import/export」를 Import.jgrapht-io★★★★★★ 。

다음은 그래프를 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;
    }
}

pom.xml다음 중 하나:

<?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>

옵션 2

하여 JGraphT에 합니다.ObjectMapper을 사용하다

다음은 예를 제시하겠습니다.

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()));
    }
}

이렇게 하면 다음과 같은 JSON 문서가 생성됩니다(예쁜 인쇄 후).

{
    "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"
            }
        ]
    }
}
import org.jgrapht.Graph;
import org.jgrapht.io.JSONExporter;
import org.jgrapht.io.SimpleGraphExporter;
import org.jgrapht.io.SimpleGraphImporter;
import org.jgrapht.io.JSONImporter;
import org.jgrapht.io.JSONExporter;
import org.jgrapht.io.ExportException;
import org.jgrapht.io.ImportException;

// Create a new, empty simple graph
Graph<String, DefaultEdge> graph = new SimpleGraph<>(DefaultEdge.class);

// Add some vertices and edges to the graph
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addEdge("A", "B");
graph.addEdge("B", "C");

// Create a new JSONExporter instance
JSONExporter<String, DefaultEdge> exporter = new JSONExporter<>();

// Export the graph to JSON
String json = exporter.toJson(graph);

언급URL : https://stackoverflow.com/questions/39438962/how-can-i-serialize-a-jgrapht-simple-graph-to-json

반응형