我graphql-spqr,java.util.Date被定义为Scalar。是否可以覆盖java.util.Date的序列化/反序列化以获取日期的其他String表示形式?
此answer中提到的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
}
}
}
答案 0 :(得分:1)
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
。您可以通过注册TypeAdapter
(只是一个映射器+转换器)而使SPQR透明地执行此操作,但是如上所述,使用一个简单的映射器在您的情况下是更有效的解决方案。如果仍然决定采用适配器方式,则可以继承AbstractTypeAdapter<Date, LocalDate>
并实现转换逻辑(应该很简单)。通过generator.withTypeAdapters
进行注册,或者将其分别注册为映射器和转换器。