如何在弹簧靴中注册自定义转换器?

时间:2015-12-12 11:59:21

标签: java spring spring-boot spring-data

我使用spring-boot-starter-jdbc(v1.3.0)编写应用程序。

我遇到的问题:BeanPropertyRowMapper的实例失败,因为它无法从java.sql.Timestamp转换为java.time.LocalDateTime

为了复制这个问题,我实施了 org.springframework.core.convert.converter.Converter这些类型。

public class TimeStampToLocalDateTimeConverter implements Converter<Timestamp, LocalDateTime> {

    @Override
    public LocalDateTime convert(Timestamp s) {
        return s.toLocalDateTime();
    }
}

我的问题是:如何为TimeStampToLocalDateTimeConverter提供BeanPropertyRowMapper

更一般的问题,我如何注册我的转换器,以使它们在系统范围内可用?

以下代码在初始化阶段将我们带到NullPointerException

private Set<Converter> getConverters() {
    Set<Converter> converters = new HashSet<Converter>();
    converters.add(new TimeStampToLocalDateTimeConverter());
    converters.add(new LocalDateTimeToTimestampConverter());

    return converters;
}

@Bean(name="conversionService")
public ConversionService getConversionService() {
    ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
    bean.setConverters(getConverters()); 
    bean.afterPropertiesSet();
    return bean.getObject();
}    

谢谢。

4 个答案:

答案 0 :(得分:1)

所有自定义转换服务都必须在FormatterRegistry中注册。尝试创建新的配置并通过实现WebMvcConfigurer来注册转换服务

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addallFormatters(FormatterRegistry registry) {
        registry.addConverter(new TimeStampToLocalDateTimeConverter());
    }
}

希望这行得通。

答案 1 :(得分:0)

我建议使用@Autowired和spring的相关依赖注入机制在整个应用程序中使用单个ConversionService实例。 ConversionService将在配置中实例化。

应用程序范围内可用的所有转换器都会收到注释(例如@AutoRegistered)。在应用程序启动时,@ Component FormatterRegistrar(类型名称本身有点误导,是的是&#34; ...注册器&#34;因为它进行注册。而@Component因为它是完全弹簧管理并需要依赖注入)将收到所有带注释的转换器的@AutoRegistered列表。

请参阅concrete implementation details的此帖子。我们在项目中使用这种机制,它就像一个魅力。

答案 2 :(得分:0)

尝试添加

@Converter(autoApply = true)

它需要放在转换器类上。如果Localdate需要Convertor与数据库进行交互,这对我来说是有效的。

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate locDate) {
      return (locDate == null ? null : Date.valueOf(locDate));
    }

    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) {
      return (sqlDate == null ? null : sqlDate.toLocalDate());
    }
}

现在与数据库交互时会自动应用。

答案 3 :(得分:0)

org.springframework.web.servlet.config.annotation.WebMvcConfigurer或其任何实现都是在Spring Boot项目中进行任何类型的自定义的一站式服务。对于您的Converter要求,它避免使用各种方法。

只需通过扩展org.springframework.core.convert.converter.Converter<S, T>创建一个新的Converter。然后通过您的类重写方法org.springframework.web.servlet.config.annotation.WebMvcConfigurer.addFormatters(FormatterRegistry)

向Spring注册它

请注意,还有其他类型的Converter也基本上从ConditionalConverter开始。