java - graphql-spqr 中的自定义标量类型
问题描述
我在graphql-spqr中,java.util.Date被定义为Scalar。是否可以覆盖 java.util.Date 的序列化/反序列化以获取日期的不同字符串表示形式?
此答案中提到的 ScalarStrategy已在最新版本中删除。
public class Order {
private String id;
private Date orderDate; //GraphQLScalarType "Date"
public Order() {
}
public Order(String id, String bookId, Date orderDate) {
this.id = id;
this.orderDate = orderDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
GraphQL 响应:
{
"data": {
"createOrder": {
"id": "74e4816c-f850-4d63-9855-e4601fa125f4",
"orderDate": "2019-05-26T08:25:01.349Z", // --> 2019-05-26
}
}
}
解决方案
ScalarStrategy
不是实现您想要的正确方法。当您想要更改 Java 类型映射到 GraphQL 的方式时,您通常会提供一个新的(或自定义现有的)TypeMapper
。
查看现有的Date
标量实现并以类似的方式实现您自己的。然后实现一个自定义TypeMapper
,它总是从toGraphQLType
和toGraphQLInputType
方法返回该标量的静态实例。
public class CustomTypeMapper implements TypeMapper {
private static final GraphQLScalarType GraphQLCustomDate = ...;
@Override
public GraphQLOutputType toGraphQLType(...) {
return GraphQLCustomDate;
}
@Override
public GraphQLInputType toGraphQLInputType(...) {
return GraphQLCustomDate;
}
@Override
public boolean supports(AnnotatedType type) {
return type.getType() == Date.class; // This mapper only deals with Date
}
}
要注册它,请调用generator.withTypeMappers(new CustomTypeMapper()
。
也就是说,由于您只是想切断时间部分,因此您最好LocalDate
在这里使用。您可以通过注册一个(只不过是一个映射器 + 转换器)使 SPQR 透明地执行此操作,TypeAdapter
但如上所述的简单映射器在您的情况下是一种更有效的解决方案。如果您仍然决定采用适配器方式,则可以继承AbstractTypeAdapter<Date, LocalDate>
并实现转换逻辑(应该是微不足道的)。通过generator.withTypeAdapters
或通过将其分别注册为映射器和转换器进行注册。
推荐阅读
- angularjs - Angularjs如何在没有hash-bang的情况下制作ngRoute
- python - Authlib 0.6+ 不适用于 Auth0 模拟和 Flask
- c# - FluentAssertions AssertionScope 上下文子路径
- ruby-on-rails - 标准化两个哈希以包含相同的键
- assimp - Assimp 编译错误 Win10 + Visual Studio 2017 社区
- r - 如何将特定组的平均值与每个单独的组进行比较?
- vb.net - 迷宫生成器删除以前的路径,只显示当前路径
- php - 使用文件大小php检查文件是否存在
- json - 如何使用 Grep 从 JSON 中保存值
- sails.js - 如何使用sails-sqlserver调用存储过程?