Maven導入Servlet-api包導致無法運行報500的問題
以下解決方式適用於跟我類似的配置環境,構建servlet程序后,啟動Tomcat頁面報“類com.tioxy.servlet.MyServlet不是Servlet,MyServlet cannot be cast to class jakarta.servlet.Servlet”或者“實例化Servlet類異常”的500錯誤的問題。
我的本機配置環境:
1.IDEA 2020.1,Tomcat 10.0.0M5,Maven 3.6.3,導入的javax.servlet-api 4.0.1
最近在學習Java Servlet,並用Maven構建的模板,導入servlet-api依賴包,寫了一個簡單的Servlet程序,就是很簡單的重寫doGet、doPost,向頁面輸出一段“hello,servlet”文本。
然后配置Tomcat服務器,跑起來控制台輸出也正常,一切看起來似乎沒什么問題,心想servlet構建起來也不過如此嘛!
當我輸入/hello,准備見證奇跡時......
這......,不是一個servlet類???,回去跟了跟代碼,確定沒寫錯啊,要不百度吧,看看網上怎么說。
哦,原來是導入的Servlet-api包與tomcat沖突,tomcat自帶了jar包,需要在自己導入的jar包上添加作用域。原來如此那么咱也加上,這不很簡單,小意思。
重新啟動,重新輸入/hello,正要准備結束一切,迎接結果時
這怎么跟剛才的錯誤還不一樣,實例化Servlet類異常,說是找不到javax/servlet/http/HttpServlet,我明明導入了jar包啊,也加了作用域了,難道我用的新版兼容性不好???
於是我想,要不不用maven依賴導包了,我自己建了一個lib目錄,把servlet-api包放到里面,然后再引用自己的包。
然后再次運行,輸入/hello
這怎么又回到第一個錯誤了,心情有點煩,這么簡單的都跑不起來,開始懷疑智商......然后檢查生成的target目錄
這也沒毛病啊,於是這樣反復兩小時,發現不加依賴包作用域,生成的target包lib目錄下有servlet-api包,加了作用域,反而沒了,於是我加了作用域,在F4模塊構件時添加servlet-api包,試了幾次還是不行,頓時心態炸了,這么簡單的玩意都搞不定,開始懷疑人生。
我又開始想,既然tomcat自帶了jar包,那我直接選用tomcat依賴不就行了。
點擊應用后,發現程序爆紅了
玩我呢,我這不添加依賴了嗎,而且還是tomcat自帶的依賴。於是我刪掉,重新寫了一遍類
咦?這不有HttpServlet嗎?為啥剛才給我爆紅,思考了三秒鍾。。。不管了,先跑起來再說。
擼完了代碼,重新啟動,抱着最后的希望,輸入/hello(說實話,在輸入的過程中,我向上帝祈禱了。。。)
嚯,終於通了,留下了激動的淚水,看了看表,距離我第一次啟動已經過去三個小時了,跑個程序是真不容易啊,簡直是玩命啊!!!,懷疑的我差點想放棄了。
成功是成功了,但是咱要分析問題,這次為什么能成功呢?還記得上面有個小疑問,為啥導入tomcat依賴,程序報錯,我自己手寫了一遍,發現是能索引出來HttpServlet的這個類。
經過反復的重試,我重新導入maven依賴包,這次tomcat與maven的兩個包同時存在。果真,真發現了貓膩:
這兩個包的包名不一致
重新看了第一次報錯500的原因,注意標注的位置,人家報的是找不到jakarta.servlet.Servlet。
於是大概明白了,Tomcat10竟然改包名了。在tomcat運行的時候,首先會加載tomcat自帶的servlet-api包,因為自己導入的包名與tomcat自帶的不一致,所以一致報錯500,真相大白!
解決方法
看了這么長苦逼的操作,總算是解決了問題,那么同樣問題的小伙伴該怎么解決呢,我提供了兩種方案:
- 降Tomcat版本,降到9版本的。
- 不用降版本,不要使用maven導入的servlet-api包,在F4的項目模塊中引入Tomcat依賴,操作步驟在上面有說明。
這只是我自己的解決方式,如果哪位小伙伴有更好的方式,也可以在評論區留言。