1. 程式人生 > >Java - Spring 支持 CORS 請求踩的坑

Java - Spring 支持 CORS 請求踩的坑

adp 頭像 cto eat tex mvc cal web 感謝

誰沒掉進過幾個大坑

記得好久之前,總能時不時在某個地方看到一些標語,往往都是上面一個偉人的頭像,然後不管是不是他說的話,下面總是有看起來很政治正確且沒卵用的屁話,我活到目前為止,最令我笑的肚子痛得是下面這段標語。

態度決定高度,思路決定出路,細節決定成敗,環境決定心境,格局決定結局。

沒錯,這是一個幹過傳銷的朋友告訴我的。

我來就講講思路

上一篇從零開始學 Java - Spring MVC 實現跨域資源 CORS 請求 中使用簡單的配置後即可實現跨域請求,但是,我在走向配置成功的路上由於我瞎,掉進了一個大坑,因為是 Spring MVC 版本 4.2 及以上才支持 CORS 配置,所以,我下載了 4.2.5 配置後一直報錯,接著我下載了 4.2.6 版本依然報這樣的錯誤

技術分享圖片

報錯信息具體代碼如下:

嚴重: StandardWrapper.Throwable
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [cors]
Offending resource: ServletContext resource [/WEB-INF/springMVC-servlet.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.fatal(FailFastProblemReporter.java:60)
at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:68)
at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:55)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.findParserForElement(NamespaceHandlerSupport.java:85)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:74)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1424)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1414)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:189)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:143)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:110)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:452)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:672)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:543)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484)
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:1282)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1195)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1085)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5349)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5641)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

我搞了整整一個上午,任何方法都嘗試了,已經快要崩潰了,依然沒解決掉。

首先,我用谷歌搜出來的信息沒有一個是可以的,接著,我去查看官方文檔、看源碼,他們也是絲毫沒有提到這個問題,我也開始懷疑人生了,你懂這種感覺的。
整個項目組的人試著各種辦法解決,依然沒有任何作用,最後大家說:要不我們還是換回老版本吧,用最原始的方式跨域?我說,你們讓我再試試吧... 這個期間,找來公司的技術大牛也來幫我解決這個問題,浪費了他老半天時間依然找不到原因,感謝他浪費時間陪我折騰。

我又加了幾個技術群,在每個群裏發這個錯誤,求解決。這期間除了幾個招聘的 HR 勾引我,還是有幾個群友出來幫我找問題的,最後我看到他們都是在用「百度一下」的時候,我也就放棄了,因為結果可想而知的。但是,我依然很感謝他們的熱情。

再接著,我去了一個技術社區發問題、提問了。我得到的結果和大家百度出來的一樣一樣的。
技術分享圖片

問題解決了

下班回到家,飯都吃不了了。第二天,到公司後,一同事告訴我:昨天晚上我回家新建了一個項目,配置後就可以成功的。我快要淚奔了,我說:昨天我們又復制一個項目去去掉所有的配置也不行的啊?然後,我倆當場又新建了一個項目,竟然啟動成功了!!!

接著,安裝剛剛的配置修改項目,依然不成功。我特麽真是日了狗了...我就去了廁所。

從廁所回來,我突然的發現,由於我們 Spring 版本升級到了4.2.6,Build Path裏的 jar 包都是導入的 4.2.6 版本的,但是但是,我沒把 4.1 的版本的刪除掉刪除掉刪除掉!!!

我到現在依然想不通的是:我們項目中導的 jar 包是 4.2.6 版本的,只是老版本的 jar 包沒從 WEB-INF\lib 下刪除,它為啥依然回去加載老版本 jar 包?

最後總結一下

這次踩的坑主要原因在於我,因為我沒及時刪除WEB-INF\lib下老版本 jar 包,因為我們當時是知道這目錄下是有老版本jar包的,大家都認為沒有影響,因為並沒有加載它。這可能是大家的一個普遍的誤區吧!

現在大家再搜索Configuration problem: Cannot locate BeanDefinitionParser for element [cors]這個錯誤信息後,會找到我的提問和這篇文章,免得大家再次走進誤區,浪費時間,那這篇文章的目的就達到了。謝謝你,看我嘮叨到最後。

因為覺得很有用,就想摘錄下來好學習。

摘自博主Mafly,鏈接:(pick me up)

Java - Spring 支持 CORS 請求踩的坑