SpringMVC同时使用<mvc:resources … />和装配自定义转换器Converter时出现问题的解决方法...

一、问题由来

在学习SpringMVC的过程中,对于URL的拦截,使用了RESTful形式,因为使用了RESTful所以,在将Servlet作为Controller中的时候,web.xml中配置拦截的url-pattern就写成了 / ,如下所示:

<servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <!-- 此处可以可以配置成 *.do ,对应struts的后缀习惯 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

如果配置成这样,对于静态资源(js,css等)也会被拦截,因为没有Controller处理器和其对应,很显然会报404的错误。

二、问题处理方式

对于此静态资源的问题,我采用了RT所示的<mvc:resources … />这种进行处理:

<mvc:resources mapping="/css/**" location="/WEB-INF/statics/css/" />
<mvc:resources mapping="/js/**" location="/WEB-INF/statics/js/" />
<mvc:resources mapping="/images/**" location="/WEB-INF/statics/images/" />
<mvc:resources mapping="/*.html" location="/" />

项目目录结构如下:

然而当把全局的Formatter<Date> 集成进去,想将字符串转成Date的转换器配置进处理器适配器时候出现问题,此时对于SpringMVC的配置是:

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

    <!-- 静态资源映射 -->
    <!-- 比如${basePath}/css/ht.css 会自动请求location中的css -->
    <mvc:resources mapping="/css/**" location="/WEB-INF/statics/css/" />
    <mvc:resources mapping="/js/**" location="/WEB-INF/statics/js/" />
    <mvc:resources mapping="/images/**" location="/WEB-INF/statics/images/" />
    <mvc:resources mapping="/*.html" location="/" />

    <!-- 日期统一转换 -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="com.mc.bsframe.formatter.DateFormatter">
                    <constructor-arg name="datePattern" value="yyyy-MM-dd HH:ss:mm" />
                </bean>
            </set>
        </property>
    </bean>

错误提示主要是:
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/statics/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]
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.ArrayList<?>] to type [org.springframework.core.io.Resource]
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:313)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
    at org.springframework.core.convert.support.CollectionToCollectionConverter.convert(CollectionToCollectionConverter.java:87)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
    ... 36 more

错误提示中最核心的部分是:Failed to convert from type [java.util.ArrayList<?>] to type [java.util.List<org.springframework.core.io.Resource>] for value '[/WEB-INF/statics/js/]'翻译出来就是:

尝试将'[/WEB-INF/statics/js/]从java.util.ArrayList<?> 转换到java.util.List<org.springframework.core.io.Resource>的时候失败了。

在用Spring3.X的时候没有这个问题出现,换成Spring4.X的时候就出现这个问题了,具体的原因不做解释,大体上就是之前的是对于资源的存储使用的是String[]现在改成了ArrayList<>造成的问题。

三、解决方法

  1. 要么移除全局的Formatter。
  2. 要么使用另外的方式进行静态资源的映射。
  3. 更换Spring版本为3.*

但一般都会使用第2个,因为转换器是必须的,而Spring版本一般不会更换,可能会使用到高版本中的一些特性或功能,具体处理步骤如下:

  1. 将会被从客户端浏览器访问的静态资源(例如js、css、html)从WEB-INF下移动到WebApp下面。
  2. 注释或删除SpringMVC配置文件中的<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>代码
  3. 在SpringMVC的xml配置中加上,它的意思就是没有映射到的URL交给默认的web容器中的servlet进行处理:
<mvc:default-servlet-handler />

最终的关键配置如下:

<mvc:annotation-driven conversion-service="conversionService" />
    <!-- 如果使用了RESTful形式的拦截,那么对于静态资源的处理上,就需要加上此句,静态资源(没有映射的)就会 -->
    <mvc:default-servlet-handler />

    <!-- 日期统一转换 -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="com.mc.bsframe.formatter.DateFormatter">
                    <constructor-arg name="datePattern" value="yyyy-MM-dd HH:ss:mm" />
                </bean>
            </set>
        </property>
    </bean>

转载于:https://my.oschina.net/ProgramerLife/blog/2966625

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值