Java GraphQL 模式中的 HashMap
HashMap in Java GraphQL schema
我正在尝试创建一个 GraphQL Spring 引导应用程序以在现有 REST Web API 之上创建一个 GraphQL 层,但我在处理架构中的 HashMap 时遇到了问题。
Timeline
class 有一个名为 dataReference
的字段,它是一个 HashMap。我尝试在 graphql 模式中将其定义为 DataReference
类型的列表,这是一个 key/value 对,但我收到以下错误:
Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:540)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.foo.bar.graphql.AppLauncher.main(AppLauncher.java:43)
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:125)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:86)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:414)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:174)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152)
... 8 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletRegistrationBean' defined in com.foo.bar.graphql.AppLauncher: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:625)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:455)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:236)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:224)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:100)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:88)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:250)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:237)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5098)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1429)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1429)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:261)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:370)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:106)
... 13 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:620)
... 55 more
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at com.coxautodev.graphql.tools.TypeClassMatcher.error(TypeClassMatcher.kt:22)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:65)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:28)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanResolverInfoForPotentialMatches(SchemaClassScanner.kt:215)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueueItemForPotentialMatches(SchemaClassScanner.kt:206)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueue(SchemaClassScanner.kt:103)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanForClasses(SchemaClassScanner.kt:81)
at com.coxautodev.graphql.tools.SchemaParserBuilder.scan(SchemaParserBuilder.kt:149)
at com.coxautodev.graphql.tools.SchemaParserBuilder.build(SchemaParserBuilder.kt:155)
at com.foo.bar.graphql.AppLauncher.servletRegistrationBean(AppLauncher.java:55)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725.CGLIB$servletRegistrationBean[=11=](<generated>)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725$$FastClassBySpringCGLIB$$c7dabbfc.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725.servletRegistrationBean(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 56 more
这是我的架构文件:
extend type Query {
getFoo: Timeline
}
type Timeline {
dataReference: [DataReference]
}
type DataReference {
key: String
value: String
}
还有我的模特class:
package com.foo.bar.graphql.model;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Getter @Setter
public class Timeline {
private Map<String, String> dataReference = new HashMap<>();
}
我发现此线程 关于在架构中定义地图的问题。在接受的答案中,选项 1) 对我来说不可行,因为模型是从现有的 Web API 中获取的,并且不能更改。上面列出了我对选项 2 的尝试,但没有奏效。我还尝试了选项 3(使用标量):
架构:
extend type Query {
getFoo: Timeline
}
scalar Object
type Timeline {
dataReference: Object
}
Servlet 注册:
@Bean
public ServletRegistrationBean servletRegistrationBean() {
GraphQLSchema schema = SchemaParser.newParser()
.resolvers(fooResolver)
.file("graphql/foo.graphqls")
.scalars(ExtendedScalars.Object)
.build()
.makeExecutableSchema();
ExecutionStrategy executionStrategy = new AsyncExecutionStrategy();
GraphQLServlet servlet = new SimpleGraphQLServlet(schema, executionStrategy);
ServletRegistrationBean bean = new ServletRegistrationBean(servlet, "/graphql");
return bean;
}
pom.xml:
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
<version>1.0</version>
</dependency>
但是我得到这个错误:Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Expected a user-defined GraphQL scalar type with name 'Object' but found none!
如果有人可以帮助我实现它,我更喜欢在模式中包含 key/value 对的方法。
最简单的方法是使用 DTO。
例如,使用像 mapstruct 这样的 DTO 映射器,将允许您 自动映射除 Map 字段 之外的所有字段,您将在其中应用转换。
你像这样创建一个 DTO :
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TimelineDTO {
private List<DataReference> dataReference = new ArrayList();
}
获取TimeLine对象后,将其映射到TimelineDTO,进行Map到List的转换。
List<DataReference> dataReferences = new ArrayList<>();
for (Map.Entry<String,String> entry : super.getDataReference().entrySet()) {
dataReferences.add(new DataReference(entry.getKey(), entry.getValue()));
}
return dataReferences;
在您的 GraphQL 合同中,您 return DTO 代替:
extend type Query {
getFoo: TimelineDTO
}
type TimelineDTO {
dataReference: [DataReference]
}
type DataReference {
key: String
value: String
}
我正在尝试创建一个 GraphQL Spring 引导应用程序以在现有 REST Web API 之上创建一个 GraphQL 层,但我在处理架构中的 HashMap 时遇到了问题。
Timeline
class 有一个名为 dataReference
的字段,它是一个 HashMap。我尝试在 graphql 模式中将其定义为 DataReference
类型的列表,这是一个 key/value 对,但我收到以下错误:
Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:540)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.foo.bar.graphql.AppLauncher.main(AppLauncher.java:43)
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:125)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:86)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:414)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:174)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152)
... 8 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletRegistrationBean' defined in com.foo.bar.graphql.AppLauncher: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:625)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:455)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:236)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:224)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:100)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:88)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:250)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:237)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5098)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1429)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1429)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:261)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:370)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:106)
... 13 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:620)
... 55 more
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='DataReference'}}) with java type (java.util.Map<java.lang.String, java.lang.String>): Java class is not a List or generic type information was lost: java.util.Map<java.lang.String, java.lang.String>
at com.coxautodev.graphql.tools.TypeClassMatcher.error(TypeClassMatcher.kt:22)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:65)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:28)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanResolverInfoForPotentialMatches(SchemaClassScanner.kt:215)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueueItemForPotentialMatches(SchemaClassScanner.kt:206)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanQueue(SchemaClassScanner.kt:103)
at com.coxautodev.graphql.tools.SchemaClassScanner.scanForClasses(SchemaClassScanner.kt:81)
at com.coxautodev.graphql.tools.SchemaParserBuilder.scan(SchemaParserBuilder.kt:149)
at com.coxautodev.graphql.tools.SchemaParserBuilder.build(SchemaParserBuilder.kt:155)
at com.foo.bar.graphql.AppLauncher.servletRegistrationBean(AppLauncher.java:55)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725.CGLIB$servletRegistrationBean[=11=](<generated>)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725$$FastClassBySpringCGLIB$$c7dabbfc.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.foo.bar.graphql.AppLauncher$$EnhancerBySpringCGLIB$ac15725.servletRegistrationBean(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 56 more
这是我的架构文件:
extend type Query {
getFoo: Timeline
}
type Timeline {
dataReference: [DataReference]
}
type DataReference {
key: String
value: String
}
还有我的模特class:
package com.foo.bar.graphql.model;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Getter @Setter
public class Timeline {
private Map<String, String> dataReference = new HashMap<>();
}
我发现此线程
架构:
extend type Query {
getFoo: Timeline
}
scalar Object
type Timeline {
dataReference: Object
}
Servlet 注册:
@Bean
public ServletRegistrationBean servletRegistrationBean() {
GraphQLSchema schema = SchemaParser.newParser()
.resolvers(fooResolver)
.file("graphql/foo.graphqls")
.scalars(ExtendedScalars.Object)
.build()
.makeExecutableSchema();
ExecutionStrategy executionStrategy = new AsyncExecutionStrategy();
GraphQLServlet servlet = new SimpleGraphQLServlet(schema, executionStrategy);
ServletRegistrationBean bean = new ServletRegistrationBean(servlet, "/graphql");
return bean;
}
pom.xml:
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
<version>1.0</version>
</dependency>
但是我得到这个错误:Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Expected a user-defined GraphQL scalar type with name 'Object' but found none!
如果有人可以帮助我实现它,我更喜欢在模式中包含 key/value 对的方法。
最简单的方法是使用 DTO。 例如,使用像 mapstruct 这样的 DTO 映射器,将允许您 自动映射除 Map 字段 之外的所有字段,您将在其中应用转换。
你像这样创建一个 DTO :
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TimelineDTO {
private List<DataReference> dataReference = new ArrayList();
}
获取TimeLine对象后,将其映射到TimelineDTO,进行Map到List的转换。
List<DataReference> dataReferences = new ArrayList<>();
for (Map.Entry<String,String> entry : super.getDataReference().entrySet()) {
dataReferences.add(new DataReference(entry.getKey(), entry.getValue()));
}
return dataReferences;
在您的 GraphQL 合同中,您 return DTO 代替:
extend type Query {
getFoo: TimelineDTO
}
type TimelineDTO {
dataReference: [DataReference]
}
type DataReference {
key: String
value: String
}