I searched a lot into SO, but unfortunately any of the proposed solutions fits to me.
I am going to describe the key points:
jaxrs-spec
generator I produce the application DTOs.graphql-nodejs-express-server
generator I produce the GraphQL schema files.The GraphQL ExecutionResult.getData()
method returns an instance of a LinkedHashMap
.
The question is: How can I marshall the above LinkedHashMap
to the corresponding DTO
?
Thank you so much in advance!
---- Edit ----
I wish to improve and simplify my question.
I have a DTO such the following one:
public class ResponseDTO {
private Integer id;
private String description;
}
I filter it by 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 = ???;
I finally found the solution:
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
);
Where fixTypeId
is:
@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()
);
});
}