environment.getArgument 无法在 graphql-java 中转换为我自己的 java 对象

Posted

技术标签:

【中文标题】environment.getArgument 无法在 graphql-java 中转换为我自己的 java 对象【英文标题】:environment.getArgument can't cast to my own java object in graphql-java 【发布时间】:2017-12-22 14:32:59 【问题描述】:

由于以下错误 ExecutionStrategy.resolveField() - 获取数据时出现异常 java.lang.ClassCastException: java.util.LinkedHashMap 与 com.fathome.graphql.OffersDto 不兼容,我无法将输入对象转换为 DTO

OffersDto inputObject = environment.getArgument("offersInput");

请让我知道下面的代码有什么问题,在此先感谢。

package com.fathome.graphql;

import graphql.schema.*;

import static graphql.Scalars.*;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLInputObjectField.newInputObjectField;
import static graphql.schema.GraphQLInputObjectType.newInputObject;
import static graphql.schema.GraphQLList.list;
import static graphql.schema.GraphQLObjectType.newObject;


public class ManualGraphQLQuerySchema 


    public static GraphQLObjectType offersResponse = newObject()
            .name("OffersResponse")
            .field(newFieldDefinition()
                    .name("offerName")
                    .type(GraphQLString))
            .field(newFieldDefinition()
                    .name("offerId")
                    .type(GraphQLString))
            .build();

    public static GraphQLInputObjectType offersRequestType = GraphQLInputObjectType.newInputObject()
            .name("OffersDto")
            .field(newInputObjectField()
                    .name("offerName")
                    .type(GraphQLString))
            .field(newInputObjectField()
                    .name("offerId")
                    .type(GraphQLString))
            .build();

    public static GraphQLObjectType queryType = newObject()
            .name("QueryType")
            .field(newFieldDefinition()
                .name("offers")
                .type(offersResponse)
                .argument(GraphQLArgument.newArgument()
                    .name("offersInput")
                    .type(offersRequestType))
                .dataFetcher(new OffersFetcher()))
            .build();





package com.fathome.graphql;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder(
        "offerName",
        "offerId"

)
public class OffersDto 

    @JsonProperty("offerName")
    private String offerName;

    @JsonProperty("offerName")
    public String getOfferName() 
        return offerName;
    

    @JsonProperty("offerName")
    public void setOfferName(String offerName) 
        this.offerName = offerName;
    

    @JsonProperty("offerId")
    private String offerId;

    @JsonProperty("offerId")
    public String getOfferId() 
        return offerId;
    

    @JsonProperty("offerId")
    public void setOfferId(String offerId) 
        this.offerId = offerId;
    





package com.fathome.graphql;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

public class OffersFetcher implements DataFetcher<OffersDto> 

    @Override
    public OffersDto get(DataFetchingEnvironment environment) 

        //Can't cast input object DTO this is error in below line
        //ExecutionStrategy.resolveField() - Exception while fetching data
        //java.lang.ClassCastException: java.util.LinkedHashMap incompatible with com.fathome.graphql.OffersDto
        OffersDto inputObject = environment.getArgument("offersInput");
       //calling service to get offerdetails using inputObject
        //for testing not calling service just returning mock object.
        OffersDto offersDto = new OffersDto();
        offersDto.setOfferName("123");
        offersDto.setOfferId("456");

        return offersDto;

    

在下面的参考链接中类似于我的代码工作正常。

剧集情节 = environment.getArgument("episode"); ReviewInput review = environment.getArgument("review");

http://graphql-java.readthedocs.io/en/latest/execution.html

【问题讨论】:

【参考方案1】:

如果是对象 GraphQL 输入类型(如您的情况),您从 environment.getArgument(...) 获得的值将是标量值(字符串、数字等)或 Map。 然后,您需要自己进行反序列化。由于您使用的是 Jackson,它看起来像这样:

private final ObjectMapper objectMapper;
...
Object rawInput = environment.getArgument("offersInput");
OffersDto inputObject = objectMapper.convertValue(rawInput, OffersDto.class);

查看graphql-java-tools 了解架构优先方法,或查看graphql-spqr 了解代码优先方法,两者都使DataFetchers 完全透明,因此不需要像上面那样的手动步骤。

【讨论】:

以上是关于environment.getArgument 无法在 graphql-java 中转换为我自己的 java 对象的主要内容,如果未能解决你的问题,请参考以下文章

ValueError 层序贯_13的输入0与层不兼容:预期ndim = 3,发现ndim = 4收到完整形状:(无,无,无,无)

如何修复'ValueError:输入0与层simple_rnn_1不兼容:预期形状=(无,无,20),找到形状=(无,无,2,20)'

树莓派3B 无显示器,无键盘,无Linux系统,无网线 配置WIFI连接

HTTP协议的 “无连接,无状态”

Visual Studio 2012 中的普通 C# 编辑器(无智能感知、无缩进、无代码突出显示)

sim卡无服务是怎么回事 手机卡突然变成无服务是怎么回事?