将 GraphQL 执行结果编组到 java 对象
Marshal GraphQL execution results to java object
我对 SO 进行了很多搜索,但不幸的是,任何建议的解决方案都适合我。
我来描述重点:
- 我的 REST 项目基于 OpenAPI 和 OpenAPI maven 生成器插件。
- 我通过
jaxrs-spec
生成器生成应用程序 DTO。
- 我通过
graphql-nodejs-express-server
生成器生成 GraphQL 架构文件。
- REST Web 服务接受一个可选的 GraphQL 查询,以便 filter/reduce 回答的冗长。
GraphQL ExecutionResult.getData()
方法 returns LinkedHashMap
的一个实例。
问题是:如何将上面的LinkedHashMap
编组到相应的DTO
?
在此先感谢您!
----
编辑
----
我希望改进和简化我的问题。
我有一个 DTO,如下所示:
public class ResponseDTO {
private Integer id;
private String description;
}
我用 GraphQL 过滤它:
GraphQLSchema graphQLSchema = getGraphQLSchema();
String graphqlQuery = "{ ResponseDTO { id } }";
ExecutionInput builder = ExecutionInput
.newExecutionInput()
.query(graphqlQuery)
.build();
ExecutionResult executionResult = GraphQL
.newGraphQL(graphQLSchema)
.build()
.execute(builder);
LinkedHashMap graphQLData = executionResult.getData();
//TODO How can I convert 'graphQLData' to a `ResponseDTO` instance?
ResponseDTO responseDTO = ???;
我终于找到了解决方案:
LinkedHashMap<String, Object> dataMap = executionResult.getData();
String dataKey = dataMap.keySet().toArray()[0].toString();
HashMap<String, Object> dataValue = (HashMap<String, Object>)dataMap.get(dataKey);
fixTypeId(
dataContext.getClass(),
dataValue
);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new JaxbAnnotationModule());
objectMapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String dataJSON = objectMapper.writeValueAsString(dataValue);
ResponseDTO responseDTO = objectMapper.readValue(
dataJSON,
ResponseDTO.class
);
其中 fixTypeId
是:
@SuppressWarnings("unchecked")
private void fixTypeId(Class<?> refClass, Map<String, Object> dataMap) {
JsonTypeInfo typeInfoAnnotation = refClass.getDeclaredAnnotation(JsonTypeInfo.class);
JsonTypeName typeNameAnnotation = refClass.getDeclaredAnnotation(JsonTypeName.class);
if ((null != typeInfoAnnotation) && (null != typeNameAnnotation)) {
String typeInfo = typeInfoAnnotation.property();
String typeName = typeNameAnnotation.value();
log.trace(
"Adding \"{} = {}\" type identifier.",
typeInfo,
typeName
);
dataMap.put(typeInfo, typeName);
}
dataMap
.entrySet()
.stream()
.filter(entry -> (entry.getValue() instanceof Map))
.forEach(entry -> {
Field field = null;
try {
field = refClass.getDeclaredField(entry.getKey());
} catch (NoSuchFieldException exception) {
log.error(exception.getMessage(), exception);
throw new RuntimeException(exception);
}
fixTypeId(
field.getType(),
(Map<String, Object>)entry.getValue()
);
});
}
我对 SO 进行了很多搜索,但不幸的是,任何建议的解决方案都适合我。
我来描述重点:
- 我的 REST 项目基于 OpenAPI 和 OpenAPI maven 生成器插件。
- 我通过
jaxrs-spec
生成器生成应用程序 DTO。 - 我通过
graphql-nodejs-express-server
生成器生成 GraphQL 架构文件。 - REST Web 服务接受一个可选的 GraphQL 查询,以便 filter/reduce 回答的冗长。
GraphQL ExecutionResult.getData()
方法 returns LinkedHashMap
的一个实例。
问题是:如何将上面的LinkedHashMap
编组到相应的DTO
?
在此先感谢您!
---- 编辑 ----
我希望改进和简化我的问题。
我有一个 DTO,如下所示:
public class ResponseDTO {
private Integer id;
private String description;
}
我用 GraphQL 过滤它:
GraphQLSchema graphQLSchema = getGraphQLSchema();
String graphqlQuery = "{ ResponseDTO { id } }";
ExecutionInput builder = ExecutionInput
.newExecutionInput()
.query(graphqlQuery)
.build();
ExecutionResult executionResult = GraphQL
.newGraphQL(graphQLSchema)
.build()
.execute(builder);
LinkedHashMap graphQLData = executionResult.getData();
//TODO How can I convert 'graphQLData' to a `ResponseDTO` instance?
ResponseDTO responseDTO = ???;
我终于找到了解决方案:
LinkedHashMap<String, Object> dataMap = executionResult.getData();
String dataKey = dataMap.keySet().toArray()[0].toString();
HashMap<String, Object> dataValue = (HashMap<String, Object>)dataMap.get(dataKey);
fixTypeId(
dataContext.getClass(),
dataValue
);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new JaxbAnnotationModule());
objectMapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String dataJSON = objectMapper.writeValueAsString(dataValue);
ResponseDTO responseDTO = objectMapper.readValue(
dataJSON,
ResponseDTO.class
);
其中 fixTypeId
是:
@SuppressWarnings("unchecked")
private void fixTypeId(Class<?> refClass, Map<String, Object> dataMap) {
JsonTypeInfo typeInfoAnnotation = refClass.getDeclaredAnnotation(JsonTypeInfo.class);
JsonTypeName typeNameAnnotation = refClass.getDeclaredAnnotation(JsonTypeName.class);
if ((null != typeInfoAnnotation) && (null != typeNameAnnotation)) {
String typeInfo = typeInfoAnnotation.property();
String typeName = typeNameAnnotation.value();
log.trace(
"Adding \"{} = {}\" type identifier.",
typeInfo,
typeName
);
dataMap.put(typeInfo, typeName);
}
dataMap
.entrySet()
.stream()
.filter(entry -> (entry.getValue() instanceof Map))
.forEach(entry -> {
Field field = null;
try {
field = refClass.getDeclaredField(entry.getKey());
} catch (NoSuchFieldException exception) {
log.error(exception.getMessage(), exception);
throw new RuntimeException(exception);
}
fixTypeId(
field.getType(),
(Map<String, Object>)entry.getValue()
);
});
}