Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 10999|回复: 0

SpringMVC同时使用和日期转换Formatter时出现问题的解决方法

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-23 16:05:49 | 显示全部楼层 |阅读模式

    很久没更新博文了,不是没有学习,而是很多东西记在OneNote里面,收获很多啊,因为各种杂事,所以对于博客很久没更新了。

    个人觉得:博客比起OneNote或者为知笔记之类的云笔不同在于博客应该记载的是比较成体系的东西,所以很多东西我准备统一回顾我学到的东西后,再成体系的更新在这里来。

    废话说多了,先处理RT的问题。

    一、问题由来

    在学习SpringMVC的过程中,对于URL的拦截,我使用了RESTful,这是一种在形式上没有动词没有后缀结尾的URL表现形式,利用PUT/POST/DELETE/GET来表示 更新、添加、删除、查找4个不同动作的一种变现形式,具体的说明,我想我可能后来会将它写成博文,但是我更推荐的是大家如果想了解这个方面的知识,请参考:http://www.ruanyifeng.com/blog/2011/09/restful.html 他才是大神。

    因为使用了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等)也会被拦截,因为没有Mapping和其对应,很显然会报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>

    错误提示是:

    2016-06-08 23:22:13,966 DEBUG org.springframework.beans.TypeConverterDelegate.convertIfNecessary() - 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/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]
        at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
        at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
        at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:173)
        at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)
        at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603)
        at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:203)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1527)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1486)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
        at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:666)
        at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:632)
        at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:680)
        at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:551)
        at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:492)
        at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
        at javax.servlet.GenericServlet.init(GenericServlet.java:158)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1238)
        at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1151)
        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1038)
        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4996)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    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<>造成的问题。

    三、解决方法

    以上说了这么多,解决方法对于大部分人来说才是最重要的。

    • 移除全局的Formatter。
    • 使用另外的方式进行静态资源的映射。

    经过考虑我使用了后者,处理步骤如下:

    1. 将静态资源从WEB-INF下移动到WebApp下面。
    2. 注释<mvc resource…>代码
    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>

    接下来对于处理静态资源,日期格式,整体搭建SSM,以及相关注意点后继续出炉。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-4 21:43 , Processed in 0.066162 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表