【问题标题】:Spring boot 2 : ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]Spring boot 2:ConverterNotFoundException:找不到能够从类型 [java.time.ZonedDateTime] 转换为类型 [java.util.Date] 的转换器
【发布时间】:2019-03-24 03:23:59
【问题描述】:

我使用的是 spring-boot 2。

我的 Junit 测试 (@SpringBootTest),我使用 org.springframework.test.web.servlet.MockMvc

@Test
@WithMockUser(roles = {"ADMIN"})
public void testGetSearchByFoodIdWithAdmin() throws Exception {
    final ResultActions resultActions = mockMvc.perform(get(RESOURCE_URL + "/search/findByFooId?fooId=123"))
                .andExpect(status().isOk());
}

我有这个转换器:

public class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
    @Override
    public Date convert(final ZonedDateTime source) {
        return source == null ? null : Date.from(source.toInstant());
    }
}

我还有这个转换器:

public class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
    @Override
    public ZonedDateTime convert(final Date source) {
        return source == null ? null : ofInstant(source.toInstant(), systemDefault());
    }
}

我有这个 Spring 配置:

@Configuration
@EnableMongoAuditing(dateTimeProviderRef = "dateTimeProvider")
public class MongoConfiguration {

    @Autowired
    MongoDbFactory mongoDbFactory;

    @Bean
    public MongoCustomConversions customConversions() {
        List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(new DateToZonedDateTimeConverter());
        converters.add(new ZonedDateTimeToDateConverter());
        return new MongoCustomConversions(converters);
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        MappingMongoConverter converter = getDefaultMongoConverter();
        //converter.afterPropertiesSet();
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
        return mongoTemplate;
    }

    @Bean
    public MappingMongoConverter getDefaultMongoConverter() throws Exception {
        MappingMongoConverter converter = new MappingMongoConverter(
                new DefaultDbRefResolver(mongoDbFactory), new MongoMappingContext());
        converter.setCustomConversions(customConversions());
        return converter;
    }

}

我有这个其他的 Spring 配置:

@Component
public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new DateToZonedDateTimeConverter());
        registry.addConverter(new ZonedDateTimeToDateConverter());
    }

}

我有这个错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]

为什么 WebMvc 部分没有考虑我的转换器,而 MongoDB 则很好?

编辑:

我使用 Spring Data Rest

@RepositoryRestResource(collectionResourceRel = "foo", path = "foo")
public interface FooRepository extends MongoRepository<Foo, String> {

    Foo findByFooId(@Param("fooId") String fooId);

}

我的Fooclass:

@Document
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class Foo {

    @Id
    private String keyid;

    @NotNull
    private String fooId;

    @CreatedDate
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime creationDate;

    @LastModifiedDate
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime updateDate;
}

编辑 n°2:

我尝试使用 CustomizedRestMvcConfiguration 实现 RepositoryRestConfigurer` 但不是我唯一的问题:

@Configuration
@EnableWebMvc
public class CustomizedRestMvcConfiguration implements RepositoryRestConfigurer {

    @Bean
    public DateToZonedDateTimeConverter dateToZonedDateTimeConverter() {
        return new DateToZonedDateTimeConverter();
    }

    @Bean
    public ZonedDateTimeToDateConverter zonedDateTimeToDateConverter() {
        return new ZonedDateTimeToDateConverter();
    }

    @Override
    public void configureConversionService(ConfigurableConversionService conversionService) {
        conversionService.addConverter(dateToZonedDateTimeConverter());
        conversionService.addConverter(zonedDateTimeToDateConverter());
    }

}

【问题讨论】:

  • 为什么MyWebMvcConfigurer 被注释为@Component 而不是@Configuration
  • 我将@Component 更改为@Configuration,但结果没有改变。
  • 当我用@GetMapping(value = "/search/findByFooId") 创建@RepositoryRestController ...我覆盖了WebMVC 部分,我没有问题。然后我得出结论,转换器在 web 部分中没有考虑到,但在 MongoDB 部分中很好地考虑到了。
  • 你有@EnableWebMvc吗?
  • 如果你删除它会发生什么?如果你想保留 Spring Boot MVC 的特性并且你想添加额外的配置,例如你不应该使用的转换器 @EnableWebMvc 根据这个doc。可以试试吗?

标签: java spring date spring-boot zoneddatetime


【解决方案1】:

MyWebMvcConfigurer 扩展了 WebMvcConfigurerAdapter,自 Spring 5.0 起已被弃用。相反,您应该实现WebMvcConfigurer 接口:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ...
    }
}

有关更多信息,请参阅 Type Conversion 文档。 还要注意不同的注释!

【讨论】:

  • 它并没有解决问题(其实我在stackoverflow上提问之前已经尝试过这个解决方案了)。
【解决方案2】:

是的,sgrillon 答案不起作用,因为问题不在于 Spring 转换,而在于 MongoDB 的 Jackson JSON 转换器。

@Document 注释 + ZonedDateTime 是问题所在。解决方案就像 sgrillion 建议的那样:“转换器”,但不是 Spring Converter / HandlerMapping。您需要将其添加到 MongoTemplate。

在此处查看以供参考。有很多 - 只是谷歌:MongoDB ZonedDateTime。

ZonedDateTime with MongoDB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-21
    • 2020-11-19
    • 2014-09-19
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 2021-11-19
    相关资源
    最近更新 更多