Register converters and converterFactories with annotations in Spring 3

前端 未结 7 1418
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 21:11

First of all ... Im relatively new in Spring, I use spring 3.x and I DONT LIKE SPRING\'S XML CONFIGURATION FILES ... I dont want for every refactoring I do, to run into XML

相关标签:
7条回答
  • 2020-12-09 21:42

    I am not sure if this works in Spring 3 but this is the solution for Spring 4:

    @Configuration
    @EnableWebMvc
    class WebMvcContext extends WebMvcConfigurerAdapter {
    
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new DateConverter("yyyy-MM-dd HH:mm:ss"));
            //registry.addConverter(anotherConverter);
        }
    }
    

    DateConverter is a custom converter:

    public class DateConverter implements Converter<String, Date>{
        private static final Logger LOGGER = LoggerFactory.getLogger(DateConverter.class);
        private final String dateFormat;
        private final SimpleDateFormat formatter;
        public DateConverter(String dateFormatPattern) {
            this.dateFormat = dateFormatPattern;
            this.formatter = new SimpleDateFormat(dateFormatPattern);
        }
    
        @Override
        public Date convert(String source) {
            Date date = null;
            try {
                date = formatter.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
    0 讨论(0)
  • 2020-12-09 21:43

    Do the following:

    @SpringBootApplication
    @PropertySources({ @PropertySource("classpath:application.properties") })
    public class YourApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    
        ConversionService conversionService = DefaultConversionService.getSharedInstance();
        ConverterRegistry converters = (ConverterRegistry) conversionService;
        converters.addConverter(new LocalDateToStringConverter());
    
        }
    
    }
    

    Where LocalDateToStringConverter looks like this.

    public class LocalDateToStringConverter implements Converter<LocalDate, String> {
    
    @Override
    public String convert(LocalDate localDate) {
        try {
    
            String date = localDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
            return date;
        } catch(DateTimeParseException ex) {
        }
        return null;
      }
    }
    
    0 讨论(0)
  • 2020-12-09 21:51

    With Spring MVC 3.2, you can create a conversion service class that extends the DefaultFormattingConversionService e.g

    ApplicationConversionService.java

    import org.springframework.format.support.DefaultFormattingConversionService;
    import org.springframework.stereotype.Component;
    
    @Component("conversionService")
    public class ApplicationConversionService extends DefaultFormattingConversionService  { 
    
        public ApplicationConversionService(){
            //DefaultFormattingConversionService's default constructor
            //creates default formatters and converters
            super(); //no need for explicit super()?
    
            //add custom formatters and converters
            addConverter(new MyConverter());
        }
    
    }
    

    and specify it in the spring config e.g

    dispatcher-servlet.xml

    <mvc:annotation-driven conversion-service="conversionService"/>
    
    0 讨论(0)
  • 2020-12-09 21:55

    First you have to define an annotation: TypeConverter

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface TypeConverter {
    }
    

    Then you have to register the conversion service and add all of the beans that have the annotation. This will be done with the following post processor:

    public class ConverterRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        registry.registerBeanDefinition("conversionService", BeanDefinitionBuilder.rootBeanDefinition(ConversionServiceFactoryBean.class).getBeanDefinition());
    }
    
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(TypeConverter.class);
        Collection converters = beansWithAnnotation.values();
        DefaultConversionService conversionService = (DefaultConversionService) beanFactory.getBean("conversionService");
        for (Object converter : converters) {
            conversionService.addConverter((Converter<?, ?>) converter);
        }
    }
    }
    

    If you need more details check this blog entry

    0 讨论(0)
  • 2020-12-09 21:55

    Automatic registration of Converter beans is also provided by Spring Boot when @EnableAutoConfiguration is turned on - see Spring Boot features. It appears that no additional annotations (other than marking each converter bean as a @Component) is required for this.

    0 讨论(0)
  • 2020-12-09 22:01

    The approach outlined by @Ralph is neat, I have +1'd his answer. Let me also recommend an alternative approach which is using @Configuration support - essentially a way to configure Spring beans using Java instead of xml. With this approach the message converters can be registered this way:

     @Configuration
     @EnableWebMvc
     @ComponentScan(...)
     public class CustomConfig extends WebMvcConfigurerAdapter {
    
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.add(new EnumConverter());
                    converters.add(new FooConverter());
                    ...
        }
    
     }
    
    0 讨论(0)
提交回复
热议问题