【问题标题】:LocalDateTime is not converted to String but to Json objectLocalDateTime 不转换为字符串,而是转换为 Json 对象
【发布时间】:2015-09-01 05:05:51
【问题描述】:

我想在调用 spring-data-rest 服务时将 java.time.LocalDateTime 类型的创建日期序列化为字符串。实体的字段使用 DateTimeFormat(iso=ISO.DATE_TIME) 进行注释。我还在 Spring 配置类中注册了一个 LocalData 到字符串转换器。

@Override
@Bean
protected ConversionService neo4jConversionService() throws Exception {
    ConversionService conversionService = super.neo4jConversionService();
    ConverterRegistry registry = (ConverterRegistry) conversionService;
    registry.removeConvertible(LocalDateTime.class, String.class);
    registry.removeConvertible(String.class, LocalDateTime.class);
    registry.addConverter(new DateToStringConverter());
    registry.addConverter(new StringToDateConverter());
    return conversionService;
}

private class DateToStringConverter implements Converter<LocalDateTime, String> {
    @Override
    public String convert(LocalDateTime source) {
        return source.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    }
}

但是没有调用转换器,创建日期被序列化为这样的Json结构:

creationDate: {
  dayOfYear: 337,
  monthValue: 12,
  hour: 10,
  minute: 15,
  second: 30,
  nano: 0,
  year: 2011,
  month: "DECEMBER",
  dayOfMonth: 3,
  dayOfWeek: "SATURDAY",
  chronology: {
  id: "ISO",
  calendarType: "iso8601"
}

这是实体定义:

@NodeEntity
public class CmmnElement {}
public class Definitions extends CmmnElement {
  @DateTimeFormat(iso = ISO.DATE_TIME)
  private LocalDateTime creationDate;
}

简单的存储库如下所示:

@RepositoryRestResource(collectionResourceRel="definitions", path="/definitions")
public interface DefinitionsRepository extends PagingAndSortingRepository<Definitions, Long>{}

creationDate 由 LocalDateTime.parse() 从这个字符串“2011-12-03T10:15:30”创建。

我在 github 上有一个示例:https://github.com/gfinger/neo4j-tests/tree/master/neo-spring-test Leaf 类有一个 LocalDateTime 类型的 creationDate。如果您运行 mvn spring-boot:run 嵌入式 Neoi4J DB 将使用 Leaf 实例进行初始化。对 http://localhost:8080/leaf%7B?page,size,sort} 的调用将日期显示为 json 结构。

我怎样才能取回这个字符串而不是 Json 对象?

【问题讨论】:

  • 你的豆子是什么样子的?你存储的实例是什么?也许通用转换器优先?
  • 版本还是3.2.2。我用实体定义和存储的实例更新帖子。
  • 您能否将其添加到您的示例项目中并再次分享链接?可能必须通过为什么Spring选择错误的序列化程序来调试......
  • 一个问题可能是转换器是上下文无关的,例如spring-data rest 可能会安装从 LocalDateTime 到 JSON 的转换器,这将覆盖你的持久性转换器......
  • 是的。我在 GitHub 上添加了一个示例。见上文。

标签: spring neo4j spring-data spring-data-neo4j spring-data-rest


【解决方案1】:

好的,抱歉耽搁了。 我检查了它,如果您查看target/cmmn.db 中的 Neo4j 数据库,它表明日期已正确序列化为字符串。

bin/neo4j-shell -path target/cmmn.db/

neo4j-sh (?)$ match (n) return *
> ;
+--------------------------------------------------------------------------------------+
| n                                                                                    |
+--------------------------------------------------------------------------------------+
| Node[0]{name:"Senat"}                                                                |
| Node[1]{name:"Cato",description:"Ceterum Censeo",creationDate:"2011-12-03T10:15:30"} |
+--------------------------------------------------------------------------------------+
2 rows

我认为问题在于 spring-data-rest 的 json-converters,它可能没有为 LocalDateTime 配置。

您必须将其添加为依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>2.4.5</version>
    </dependency>

然后叶子被渲染为:

  "name" : "Cato",
  "description" : "Ceterum Censeo",
  "creationDate" : "2011-12-03T10:15:30",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/leaf/7"
    }

见:https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#customizing-the-jackson-objectmapper

【讨论】:

  • 是的,超级。对于 spring-data-rest 存储库,对 jackson-datatype-jsr310 的依赖可以完成这项工作。但是从我自己的 RestControllers 返回时,我的自定义转换器仍然被忽略。这是否需要另外配置转换服务?
【解决方案2】:

我在 spring mvc 中遇到了类似的问题。添加 jackson-datatype-jsr310 的依赖项并不能解决我的问题,而是自定义格式化程序完成了这项工作。

在这里我发现https://stackoverflow.com/a/34548741/9091816

public class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime>{
    private static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
    
    @Override
    public void serialize(LocalDateTime dateTime, JsonGenerator generator, SerializerProvider sp)
            throws IOException, JsonProcessingException {
        String formattedDateTime = dateTime.format(DateTimeFormatter.ofPattern(dateTimeFormat)); 
        generator.writeString( formattedDateTime);
    }
}

并在您的 LocalDateTime 字段中使用该自定义序列化程序:

@JsonSerialize(using = CustomLocalDateTimeSerializer.class)
private LocalDateTime creationDate;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-27
    • 2020-01-03
    • 1970-01-01
    • 2018-05-03
    • 2019-08-07
    • 2019-08-27
    • 2020-05-27
    相关资源
    最近更新 更多