Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回HashMap<;字符串,对象>;来自GraphQLJava_Java_Graphql_Graphql Java - Fatal编程技术网

返回HashMap<;字符串,对象>;来自GraphQLJava

返回HashMap<;字符串,对象>;来自GraphQLJava,java,graphql,graphql-java,Java,Graphql,Graphql Java,我尝试了一些变体,但没有运气返回GraphQL中的地图。因此,我有以下两个对象: public class Customer { private String name, age; // getters & setters } public class Person { private String type; private Map<String, Customer> customers; // getters & sette

我尝试了一些变体,但没有运气返回GraphQL中的地图。因此,我有以下两个对象:

public class Customer {

    private String name, age;
    // getters & setters
}

public class Person {

   private String type;
   private Map<String, Customer> customers;
   // getters & setters
}
有人能告诉我如何实现这一点,让GraphQL神奇地处理这一点或另一种方法吗


非常感谢

GraphQL()中没有映射类型

另一种方法是将
客户
作为
客户
列表

public class Person {
   private String type;
   private List<Customer> customers;
}
模式基本上保持不变

type Customer {
   key: String! // or another meaningful name
   name: String!
   age: String!
}

type Person {
  type: String!
  customers: [Customer!]!
}

正如您自己所指出的,GraphQL中没有映射类型,主要是因为映射基本上是非类型化数据(或具有动态结构的数据),因此不能很好地转换为GraphQL所期望的静态类型。不过,你还有一些选择

1) 您可以更改值类型,使其包含键,然后放弃映射,改为使用列表。这是你在自己的回答中采取的方法。我不会在这里详细说明,因为您已经举例说明了这一点

2) 只要键和值Java类型已知(而不是例如
对象
),就可以将映射视为键-值对列表。您可以创建一个类型来表示该对:

type Person {
  type: String!
  customers: [CustomerEntry!]
}

type CustomerEntry {
  key: String!
  value: Customer!
}
另一方面,你现在有了更难看的问题:

{
   person {
     type
     customers {
       key
       value {
         name
       }
     }
   }
}
另一方面,您保持了类型安全性和(主要)语义。可以继续嵌套这种方法,例如表示
地图

3) 如果您有一个完全未知的类型,即
对象
,那么唯一的选择就是将其视为复杂标量。在JavaScript中,这种方法被称为JSON,因为它归结为在其中填充任意JSON结构并将其视为标量。同样的方法也可以在Java中实现。GraphQLJava现在有一个用于的项目。下面是它们的(别名为)实现

现在,如果您想要表示一个类型,例如
Map
,您可以选择使用上面的键值对方法来表示它,其中只有值类型是JSON标量,或者您可以将整个映射表示为JSON标量

type MapEntry {
  key: String!
  value: [ObjectScalar!]
}

scalar ObjectScalar
事实上,您可以决定将任何映射(实际上是任何类型,但这并不有用)表示为JSON标量

type MapEntry {
  key: String!
  value: [ObjectScalar!]
}

scalar ObjectScalar
从正面来看,现在可以精确地保持任何动态结构的形状。
另一方面,由于它是一个标量,所以不可能进行子选择,而且在不事先知道内部内容的情况下,您将无法获取所有子选择。

以防万一-您可以始终将映射对象表示为JSON字符串(在我的情况下,这很有帮助)

在此之后,不要忘记添加数据获取程序,将其转换为JSON

public DataFetcher<String> fetchCustomers() {
        return environment -> {
            Person person = environment.getSource();
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                return objectMapper.writeValueAsString(person.getCustomers());
            } catch (JsonProcessingException e) {
                log.error("There was a problem fetching the person!");
                throw new RuntimeException(e);
            }
        };
    }

之后,您可以像处理客户端中的典型JSON字符串一样处理客户。

“主要是因为地图基本上是非类型化数据”。我不同意。在我看来,映射的类型和数组的类型一样。set/hashset如何?@KokHowTeh GraphQL为什么要这样做?Java就是这样做的。@yami您需要一个条目列表,类似于
列表
。例如,请参见实施。@yami不是地图列表,而是条目列表。我真的不能再帮你了。
public class Person {

    private String type;
    private Map<String, Customer> customers;
    // getters & setters
}
type Person {
  type: String!
  customers: String!
}
public DataFetcher<String> fetchCustomers() {
        return environment -> {
            Person person = environment.getSource();
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                return objectMapper.writeValueAsString(person.getCustomers());
            } catch (JsonProcessingException e) {
                log.error("There was a problem fetching the person!");
                throw new RuntimeException(e);
            }
        };
    }
"person": {
    "type": "2",
    "customers": "{\"VIP\":{\"name\":\"John\",\"age\":\"19\"},\"Platinum VIP\":{\"name\":\"Peter\",\"age\":\"65\"}}"
  }