首页 > 解决方案 > DGraph:在检索链接数据时获取 JSON 语法异常

问题描述

我是新手DGraph。所以,我正在试验dgraph4j样本并对其进行了一些修改。

在示例中,我尝试查询以下数据:

{
   "all":[
      {
         "name":"Alice",
         "friend":{
            "name":"Bob"
         }
      },
      {
         "name":"Bob"
      }
   ]
}

但是一旦我运行以下程序:

import com.google.gson.Gson;
import com.google.protobuf.ByteString;
import io.dgraph.DgraphClient;
import io.dgraph.DgraphClient.Transaction;
import io.dgraph.DgraphGrpc;
import io.dgraph.DgraphGrpc.DgraphBlockingStub;
import io.dgraph.DgraphProto.Mutation;
import io.dgraph.DgraphProto.Operation;
import io.dgraph.DgraphProto.Response;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class AppLink {
    private static final String TEST_HOSTNAME = "localhost";
    private static final int TEST_PORT = 9080;

    public static void main(final String[] args) {
        ManagedChannel channel =
                ManagedChannelBuilder.forAddress(TEST_HOSTNAME, TEST_PORT).usePlaintext(true).build();
        DgraphBlockingStub blockingStub = DgraphGrpc.newBlockingStub(channel);
        DgraphClient dgraphClient = new DgraphClient(Collections.singletonList(blockingStub));

        // Initialize
        dgraphClient.alter(Operation.newBuilder().setDropAll(true).build());

        // Set schema
        String schema = "name: string @index(exact) .";
        Operation op = Operation.newBuilder().setSchema(schema).build();
        dgraphClient.alter(op);

        Gson gson = new Gson(); // For JSON encode/decode

        Transaction txn = dgraphClient.newTransaction();
        try {
            // Create data
            Person p1 = new Person();
            p1.name = "Alice";
            Person p2 = new Person();
            p2.name = "Bob";
            p1.friend = p2;

            People ppl = new People();
            ppl.all = new ArrayList<>();
            ppl.all.add(p1);
            ppl.all.add(p2);

            // Serialize it
            String json = gson.toJson(ppl);

            // Run mutation
            Mutation mu =
                    Mutation.newBuilder().setSetJson(ByteString.copyFromUtf8(json)).build();
            txn.mutate(mu);
            txn.commit();

        } finally {
            txn.discard();
        }
        // Query
        String query =
                "query all($a: string){\n" + "all(func: eq(name, $a)) {\n" + "    name\n" + "    friend{name}\n" + "  }\n" + "}";
        Map<String, String> vars = Collections.singletonMap("$a", "Alice");
        Response res = dgraphClient.newTransaction().queryWithVars(query, vars);

        // Deserialize
        People ppl = gson.fromJson(res.getJson().toStringUtf8(), People.class);

        // Print results
        System.out.printf("people found: %d\n", ppl.all.size());
        ppl.all.forEach(person -> {
            System.out.println(person.name);
            System.out.println(person.friend);
        });
    }

    static class Person {
        String name;
        Person friend;

        Person() {}
    }

    static class People {
        List<Person> all;

        People() {}
    }
}

我得到了JsonSyntaxException——

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 35 path $.all[0].friend
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
        at com.google.gson.Gson$FutureTypeAdapter.read(Gson.java:969)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
        at com.google.gson.Gson.fromJson(Gson.java:887)
        at com.google.gson.Gson.fromJson(Gson.java:852)
        at com.google.gson.Gson.fromJson(Gson.java:801)
        at com.google.gson.Gson.fromJson(Gson.java:773)
        at AppLink.main(AppLink.java:74)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 35 path $.all[0].friend
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
        ... 13 more

谁能帮我解决它?

标签: javajsondgraph

解决方案


看起来问题在于res.getJson()它试图将对象数组转换为人员数组,不幸的是,gson 无法创建从 JSON 数组到对象数组的直接解析,您需要提取“全部”并且您需要获取它的数组才能解析和不是整个对象

你需要创建类似的东西

List<People> people;    
Type listType = new TypeToken<List<People>>() {
                    }.getType();
 people= new Gson().fromJson(new JSONObject(res.getJson().toStringUtf8()).getJSON("all").toString(), listType);

推荐阅读