Spring自定义转换器被覆盖

时间:2017-09-18 16:45:31

标签: java spring spring-mvc spring-rest

这是我的第一篇文章,所以如果我错过了任何发布好问题的惯例,请原谅。

我使用Spring REST编写RESTful服务。服务的签名如下。

@RestController
@RequestMapping(value = "/{param1}/{param2}/myservice", produces = MediaType.APPLICATION_JSON_VALUE)
public class MyService {

    @RequestMapping(value = "/{param3}", method = GET)
    public MyResponseObj getMyResponseDetails(MyRequestObject request){
        //Service logic code
    }
}

在上面的示例中, MyRequestObject 包含具有特定格式的自定义日期对象。有关此问题的参考, MyReateObject MyDate 的自定义日期对象的名称为 myDate

我的目标是将 myDate 的字符串值转换为名称为 myDate 的查询参数。我故意保持查询参数名称与 MyRequestObject 类中的内部对象名称相同,以便Spring可以隐式地将值赋给 myDate 属性> MyRequestObject 方法参数的实例。为了进行这种自动分配,我确保使用String参数保留 MyDate 的构造函数。但是,Spring不会为 myDate 值执行此自动分配。

因此,在阅读了此论坛上的几篇文章后,我创建了一个自定义转换器,将 String 对象转换为 MyDate 对象。下面是我的相同代码。

@Component
public class StringToMyDateConverter implements Converter<String, MyDate> {
    public MyDate convert(String s){
        //MyDate.parseData(String) is a custom method to convert a String to MyDate object
        return MyDate.parseData(s);
    }
}

然后,我在Spring config.xml文件中添加了以下配置,将此自定义转换器类添加到Spring的默认转换服务中。

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.my.service.rest.util.conversion.StringToMyDateConverter"/>
        </set>
    </property>
</bean>

在调试期间启动应用程序期间,我发现我的自定义转换器代码正在执行,而Spring的默认转换器服务注册了我的自定义转换器。但是,我还注意到Spring初始化 FormattingConversionServiceFactoryBean 的内部代码在启动服务期间会多次执行。这最终导致覆盖转换器服务列表,该列表没有我之前注册的自定义转换器。

因此,当我调用下面提到的REST服务URL时,我得到以下提到的错误。

网址     http://localhost:7880/project/json/value1/value2/myservice/value3?myDate=2017-09-12

异常

org.springframework.validation.BindException: 
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'request' on field 'myDate': rejected value [2017-09-12]; codes [typeMismatch.request.myDate,typeMismatch.myDate,typeMismatch.com.my.service.xml.datatype.MyDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [request.myDate,myDate]; arguments []; default message [myDate]]; default message [Failed to convert property value of type [java.lang.String] to required type [com.my.service.xml.datatype.MyDate] for property 'myDate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.my.service.xml.datatype.MyDate] for property 'myDate': no matching editors or conversion strategy found]

重要的是要提到我的项目有一个复杂的模块结构,有多个Spring配置。

我认为,因为Spring正在多次初始化默认转换服务。但是,我无法确定配置调用的顺序,因此我可以阻止Spring覆盖列表中添加的客户配置。我也尝试了下面列出的基于注释的配置类来实现这个结果。但这也导致了同样的问题。

@Configuration
public class ConversionServiceProvider {
    @Autowired
    private StringToMyDateConverter stringToMyDateConverter;

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

    private Set<Converter<?, ?>> getConverters() {
        Set<Converter<?, ?>> converters = new HashSet<>();

        converters.add(stringToMyDateConverter);
        // add here more custom converters, either as spring bean references or directly instantiated

        return converters;
    }
}

你可以告诉我一些我可以尝试解决这个问题的方法吗?请原谅我这个冗长的问题,但我认为这有助于更好地了解情况和问题。

谢谢!

0 个答案:

没有答案