通过查询模式通过子对象访问父对象的受保护字段
Posted
技术标签:
【中文标题】通过查询模式通过子对象访问父对象的受保护字段【英文标题】:Access to protected field of parent object through child object via a query schema 【发布时间】:2019-11-10 04:05:34 【问题描述】:我正在使用graphql-spqr,这样我就不必创建schema.graphql
文件。
我有一个基类,我的大多数其他类都继承自该基类。例如
@GraphQLInterface(name = "BaseResponse", implementationAutoDiscovery = true)
@ToString
@Data
public class BaseResponse
@JsonInclude(Include.NON_NULL)
protected String responseCode;
@JsonInclude(Include.NON_NULL)
protected String responseDescription;
protected String hash;
其他类继承自上述基类如下
@ToString(callSuper = true)
@Data
@AllArgsConstructor
public class GetAllGroupResponse extends BaseResponse
private List<Group> groups;
当我像下面这样设置GetAllGroupResponse
的父值时
getAllGroupResponse.setResponseCode(ResponseCodeEnum.SH_97.getRespCode());
getAllGroupResponse.setResponseDescription(ResponseCodeEnum.SH_97.getRespDescription());
我希望从我的 graphql 查询请求中检索 responseCode 的值
getAllPagable(pageNumber : 1, numberOfRecords : 3) responseCode groups groupName
但它会在下面抛出一个错误,告诉我它看不到 responseCode 变量,因为它不是 GetAllGroupResponse
类的直接属性
FieldUndefined 类型的验证错误:“GetAllGroupResponse”类型中的字段“responseCode”未定义@“getAllPagable/responseCode”
PS。 BaseResponse
来自导入到当前项目的不同包/库项目
更新
基于提出的 GitHub 问题和提供的解决方案。我创建了一个如下的bean
@Bean
public ExtensionProvider<GeneratorConfiguration, ResolverBuilder> resolverBuilderExtensionProvider()
String[] packages = "com.sheeft.microservices.library", "com.sheeft.mircoservice.groups";
return (config, current) ->
List<ResolverBuilder> resolverBuilders = new ArrayList<>();
//add a custom subtype of PublicResolverBuilder that only exposes a method if it's called "greeting"
resolverBuilders.add(new PublicResolverBuilder()
@Override
public PublicResolverBuilder withBasePackages(String... basePackages)
return super.withBasePackages(packages); //To change body of generated methods, choose Tools | Templates.
);
//add the default builder
resolverBuilders.add(new AnnotatedResolverBuilder().withBasePackages(packages));
return resolverBuilders;
;
现在我收到一个错误,上面写着以下内容
对象类型“GetAllGroupResponse”未实现接口“BaseResponse”,因为缺少字段“responseCode”
所以我决定手动添加getResponseCode
getter 方法,它运行成功。当我调用/graphql
端点时,它会引发异常
对象必须不为空", "trace": "graphql.AssertException: 对象要求不为空
【问题讨论】:
【参考方案1】:我认为您所需要的只是为您的项目设置基础包。例如
generator.withBasePackages("your.root.package", "library.root.package")
或者,如果您使用的是 SPQR Spring Starter,请添加
graphql.spqr.base-packages=your.root.package,library.root.package
到您的application.properties
文件,效果相同。
当您有跨多个包(甚至库,如您的情况)的类层次结构时需要这样做,以让 SPQR 知道应该公开哪些包,否则它可能会意外公开一些框架代码甚至核心 Java 内容比如getClass。
【讨论】:
@alexdavies 你做了很多不必要的怪事,你不需要这些。试试我告诉你的。而且你没有提到你正在使用 SPQR Spring Starter,这是重要的信息。 我按照要求做了,我收到以下错误object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'hash' is missing object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseCode' is missing object type 'GetAllGroupResponse' does not implement interface 'BaseResponse' because field 'responseDescription' is missing
我深表歉意。我使用的是旧版本的库版本 0.03 我切换到版本 0.05 现在可以使用了。以上是关于通过查询模式通过子对象访问父对象的受保护字段的主要内容,如果未能解决你的问题,请参考以下文章