简体   繁体   中英

Spring MVC “No converter found capable of converting from type java.lang.String to type org.springframework.core.io.Resource”

We have a number of custom "org.springframework.core.convert.converter.Converter" converters that help us automatically map URL params in rest requests to our domain objects.

Today we have these converters registered by defining a conversion service:

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <!-- List of custom converter beans here -->
        </set>
    </property>
</bean>

and then registering it using:

<mvc:annotation-driven conversion-service="conversionService" />

However we get the following exception on startup for each of our definitions:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.ArrayList<?> to type java.util.List<org.springframework.core.io.Resource> for value '[/WEB-INF/images/]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.String to type org.springframework.core.io.Resource

Has anyone encountered / resolved this before?

We are using spring 3.2.9.

Im glad you got it sorted anyway. I pulled the project and ran it myself anyway just to take a look and your explanation is correct. You could add this to your log4j.xml if you wanted to get rid of that message from polluting your logs in the future :-)

<logger name="org.springframework.beans.TypeConverterDelegate">
    <level value="error" />
</logger>

Turns out this was just me not reading the line above the stack trace properly... missed the fact that the line above the stack was "DEBUG".

In short, the conversion service is unable to convert from a String to a Resource; however, spring falls back on it's PropertyEditor-based conversion which succeeds (I believe this is how String-Resource conversions are done normally).

I created a sample project that will re-create this debug exception: https://github.com/jamiecramb/pastebin/tree/master/conversion-test .

Example of the full stack was as follows:

DEBUG: org.springframework.beans.TypeConverterDelegate - Original ConversionService attempt failed - ignored since PropertyEditor based conversion eventually succeeded
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.ArrayList<?> to type java.util.List<org.springframework.core.io.Resource> for value '[/WEB-INF/css/]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.String to type org.springframework.core.io.Resource
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:168)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161)
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:494)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:488)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1463)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5198)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5481)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:634)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:671)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1840)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.String to type org.springframework.core.io.Resource
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:276)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:171)
    at org.springframework.core.convert.support.CollectionToCollectionConverter.convert(CollectionToCollectionConverter.java:83)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
    ... 40 more

I just had the error with Spring 4.1.1 and the same definition of FormattingConversionServiceFactoryBean .

Hiding logs won't resolve the issue... and in my opinion, it's not a viable solution, especially for production.

I fixed it by changing <set></set> to <list></list> .

I also met this question recently.

My Spring version is 4.1.x.In the beginning,I only use the FormattingConversionServiceFactoryBean to config my customed converter like this:

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="registerDefaultFormatters" value="false" />
    <property name="converters">
        <set>
            <bean class="com.example.controller.converter.CustomerStringToDateConverter"/>
        </set>
    </property>
</bean>

<mvc:annotation-driven conversion-service="conversionService"/>

It works well.

But when I use the "Serving of Resources",it throws exception

<mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>

DEBUG [RMI TCP Connection(3)-127.0.0.1] - Original ConversionService attempt failed - ignored since PropertyEditor based conversion eventually succeeded
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.ArrayList<?> to type java.util.List<org.springframework.core.io.Resource> for value '[/js/]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.ArrayList<?> to type org.springframework.core.io.Resource

The way to solve this question is change the id name of the "FormattingConversionServiceFactoryBean" ,for example "conversionService2".

<mvc:annotation-driven conversion-service="conversionService"/>

and change this refer at the same time

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM