目前格式:HTML/XML
既然你使用的是 Spring 6、Java 17 並且在 Tomcat 10 上執行,這是一個完全 Jakarta EE 的環境。
Spring 6 的核心變化是全面捨棄了 javax.*,改用 jakarta.*。你之前看到的報錯 No qualifying bean of type 'javax.sql.DataSource' 很可能是因為你的程式碼或設定還在使用舊的命名空間,或者 Spring 在查找 JNDI 時沒有正確對接。
以下是針對 Spring 6 + Tomcat 10 的標準配置指南:
1. 確認 server.xml 配置
請確保你的 driverClassName 使用的是最新版的驅動類別,且資源已定義在 <GlobalNamingResources> 或專案的 <Context> 中。
XML
<Resource name="jdbc/MyMssqlDS"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://localhost:1433;databaseName=YourDB;encrypt=true;trustServerCertificate=true;"
username="sa"
password="YourPassword"
maxTotal="20"/>
注意:SQL Server 新版驅動預設開啟 SSL,若為本地測試,建議加上 encrypt=true;trustServerCertificate=true; 以免連線被拒絕。
2. Spring 6 的 Java 配置 (最推薦)
在 Spring 6 中,建議使用 JndiDataSourceLookup 來獲取 Tomcat 提供的資料源。
Java
import jakarta.sql.DataSource; // 注意是 jakarta
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
@Configuration
public class DataConfig {
@Bean
public DataSource dataSource() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
// 如果 resource-ref 設為 true,Spring 會自動加上 java:comp/env/ 前綴
return lookup.getDataSource("jdbc/MyMssqlDS");
}
}
3. 檢查 pom.xml 關鍵依賴
請確保你的依賴版本正確,特別是 MSSQL Driver 和 Spring JDBC。
XML
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.x</version> </dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.4.2.jre17</version>
</dependency>
</dependencies>
4. 解決 javax vs jakarta 的衝突
你的截圖顯示 Spring 正在尋找 javax.sql.DataSource。
如果你的代碼是: import javax.sql.DataSource;
請修改為: import jakarta.sql.DataSource;
原因: Spring 6 的 JdbcTemplate 或 LocalContainerEntityManagerFactoryBean 預期注入的是 jakarta 類型的 Bean。如果類型不匹配,即使你定義了 Bean,Spring 也會說找不到。
🛠️ 排查檢查清單
Jar 檔位置:mssql-jdbc-xxx.jre17.jar 是否已放入 Tomcat 的 /lib 目錄?(重要: 修改後需重啟 Tomcat)。
web.xml:是否加入了 <resource-ref>?
XML
<resource-ref>
<res-ref-name>jdbc/MyMssqlDS</res-ref-name>
<res-type>jakarta.sql.DataSource</res-type> <res-auth>Container</res-auth>
</resource-ref>
錯誤訊息變化:修改為 jakarta 後,如果報錯變成 NameNotFoundException,代表 Spring 找得到路徑但 Tomcat 沒提供,這時請檢查 server.xml 的 name 是否拼錯。
你想讓我幫你檢查你的 server.xml 內容,看看 Resource 標籤寫得對不對嗎?
5pei54S25L2g5L2/55So55qE5pivIFNwcmluZyA244CBSmF2YSAxNyDkuKbkuJTlnKggVG9tY2F0IDEwIOS4iuWft+ihjO+8jOmAmeaYr+S4gOWAi+WujOWFqCBKYWthcnRhIEVFIOeahOeSsOWig+OAggoKCgpTcHJpbmcgNiDnmoTmoLjlv4PororljJbmmK/lhajpnaLmjajmo4TkuoYgamF2YXguKu+8jOaUueeUqCBqYWthcnRhLirjgILkvaDkuYvliY3nnIvliLDnmoTloLHpjK8gTm8gcXVhbGlmeWluZyBiZWFuIG9mIHR5cGUgJ2phdmF4LnNxbC5EYXRhU291cmNlJyDlvojlj6/og73mmK/lm6DngrrkvaDnmoTnqIvlvI/norzmiJboqK3lrprpgoTlnKjkvb/nlKjoiIrnmoTlkb3lkI3nqbrplpPvvIzmiJbogIUgU3ByaW5nIOWcqOafpeaJviBKTkRJIOaZguaykuacieato+eiuuWwjeaOpeOAggoKCgrku6XkuIvmmK/ph53lsI0gU3ByaW5nIDYgKyBUb21jYXQgMTAg55qE5qiZ5rqW6YWN572u5oyH5Y2X77yaCgoKCjEuIOeiuuiqjSBzZXJ2ZXIueG1sIOmFjee9rgoK6KuL56K65L+d5L2g55qEIGRyaXZlckNsYXNzTmFtZSDkvb/nlKjnmoTmmK/mnIDmlrDniYjnmoTpqYXli5XpoZ7liKXvvIzkuJTos4fmupDlt7LlrprnvqnlnKggPEdsb2JhbE5hbWluZ1Jlc291cmNlcz4g5oiW5bCI5qGI55qEIDxDb250ZXh0PiDkuK3jgIIKCgoKWE1MCgoKCjxSZXNvdXJjZSBuYW1lPSJqZGJjL015TXNzcWxEUyIKCiAgICAgICAgICBhdXRoPSJDb250YWluZXIiCgogICAgICAgICAgdHlwZT0iamF2YXguc3FsLkRhdGFTb3VyY2UiCgogICAgICAgICAgZHJpdmVyQ2xhc3NOYW1lPSJjb20ubWljcm9zb2Z0LnNxbHNlcnZlci5qZGJjLlNRTFNlcnZlckRyaXZlciIKCiAgICAgICAgICB1cmw9ImpkYmM6c3Fsc2VydmVyOi8vbG9jYWxob3N0OjE0MzM7ZGF0YWJhc2VOYW1lPVlvdXJEQjtlbmNyeXB0PXRydWU7dHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZT10cnVlOyIKCiAgICAgICAgICB1c2VybmFtZT0ic2EiCgogICAgICAgICAgcGFzc3dvcmQ9IllvdXJQYXNzd29yZCIKCiAgICAgICAgICBtYXhUb3RhbD0iMjAiLz4KCuazqOaEj++8mlNRTCBTZXJ2ZXIg5paw54mI6amF5YuV6aCQ6Kit6ZaL5ZWfIFNTTO+8jOiLpeeCuuacrOWcsOa4rOippu+8jOW7uuitsOWKoOS4iiBlbmNyeXB0PXRydWU7dHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZT10cnVlOyDku6XlhY3pgKPnt5rooqvmi5LntZXjgIIKCgoKMi4gU3ByaW5nIDYg55qEIEphdmEg6YWN572uICjmnIDmjqjolqYpCgrlnKggU3ByaW5nIDYg5Lit77yM5bu66K2w5L2/55SoIEpuZGlEYXRhU291cmNlTG9va3VwIOS+hueNsuWPliBUb21jYXQg5o+Q5L6b55qE6LOH5paZ5rqQ44CCCgoKCkphdmEKCgoKaW1wb3J0IGpha2FydGEuc3FsLkRhdGFTb3VyY2U7IC8vIOazqOaEj+aYryBqYWthcnRhCgppbXBvcnQgb3JnLnNwcmluZ2ZyYW1ld29yay5jb250ZXh0LmFubm90YXRpb24uQmVhbjsKCmltcG9ydCBvcmcuc3ByaW5nZnJhbWV3b3JrLmNvbnRleHQuYW5ub3RhdGlvbi5Db25maWd1cmF0aW9uOwoKaW1wb3J0IG9yZy5zcHJpbmdmcmFtZXdvcmsuamRiYy5kYXRhc291cmNlLmxvb2t1cC5KbmRpRGF0YVNvdXJjZUxvb2t1cDsKCgoKQENvbmZpZ3VyYXRpb24KCnB1YmxpYyBjbGFzcyBEYXRhQ29uZmlnIHsKCgoKICAgIEBCZWFuCgogICAgcHVibGljIERhdGFTb3VyY2UgZGF0YVNvdXJjZSgpIHsKCiAgICAgICAgSm5kaURhdGFTb3VyY2VMb29rdXAgbG9va3VwID0gbmV3IEpuZGlEYXRhU291cmNlTG9va3VwKCk7CgogICAgICAgIC8vIOWmguaenCByZXNvdXJjZS1yZWYg6Kit54K6IHRydWXvvIxTcHJpbmcg5pyD6Ieq5YuV5Yqg5LiKIGphdmE6Y29tcC9lbnYvIOWJjee2tAoKICAgICAgICByZXR1cm4gbG9va3VwLmdldERhdGFTb3VyY2UoImpkYmMvTXlNc3NxbERTIik7CgogICAgfQoKfQoKMy4g5qqi5p+lIHBvbS54bWwg6Zec6Y215L6d6LO0Cgroq4vnorrkv53kvaDnmoTkvp3os7TniYjmnKzmraPnorrvvIznibnliKXmmK8gTVNTUUwgRHJpdmVyIOWSjCBTcHJpbmcgSkRCQ+OAggoKCgpYTUwKCgoKPGRlcGVuZGVuY2llcz4KCiAgICA8ZGVwZW5kZW5jeT4KCiAgICAgICAgPGdyb3VwSWQ+b3JnLnNwcmluZ2ZyYW1ld29yazwvZ3JvdXBJZD4KCiAgICAgICAgPGFydGlmYWN0SWQ+c3ByaW5nLWpkYmM8L2FydGlmYWN0SWQ+CgogICAgICAgIDx2ZXJzaW9uPjYuMS54PC92ZXJzaW9uPiA8L2RlcGVuZGVuY3k+CgoKCiAgICA8ZGVwZW5kZW5jeT4KCiAgICAgICAgPGdyb3VwSWQ+Y29tLm1pY3Jvc29mdC5zcWxzZXJ2ZXI8L2dyb3VwSWQ+CgogICAgICAgIDxhcnRpZmFjdElkPm1zc3FsLWpkYmM8L2FydGlmYWN0SWQ+CgogICAgICAgIDx2ZXJzaW9uPjEyLjQuMi5qcmUxNzwvdmVyc2lvbj4KCiAgICA8L2RlcGVuZGVuY3k+Cgo8L2RlcGVuZGVuY2llcz4KCjQuIOino+axuiBqYXZheCB2cyBqYWthcnRhIOeahOihneeqgQoK5L2g55qE5oiq5ZyW6aGv56S6IFNwcmluZyDmraPlnKjlsIvmib4gamF2YXguc3FsLkRhdGFTb3VyY2XjgIIKCgoK5aaC5p6c5L2g55qE5Luj56K85piv77yaIGltcG9ydCBqYXZheC5zcWwuRGF0YVNvdXJjZTsKCgoK6KuL5L+u5pS554K677yaIGltcG9ydCBqYWthcnRhLnNxbC5EYXRhU291cmNlOwoKCgrljp/lm6DvvJogU3ByaW5nIDYg55qEIEpkYmNUZW1wbGF0ZSDmiJYgTG9jYWxDb250YWluZXJFbnRpdHlNYW5hZ2VyRmFjdG9yeUJlYW4g6aCQ5pyf5rOo5YWl55qE5pivIGpha2FydGEg6aGe5Z6L55qEIEJlYW7jgILlpoLmnpzpoZ7lnovkuI3ljLnphY3vvIzljbPkvb/kvaDlrprnvqnkuoYgQmVhbu+8jFNwcmluZyDkuZ/mnIPoqqrmib7kuI3liLDjgIIKCgoK8J+boO+4jyDmjpLmn6XmqqLmn6XmuIXllq4KCkphciDmqpTkvY3nva7vvJptc3NxbC1qZGJjLXh4eC5qcmUxNy5qYXIg5piv5ZCm5bey5pS+5YWlIFRvbWNhdCDnmoQgL2xpYiDnm67pjITvvJ/vvIjph43opoHvvJog5L+u5pS55b6M6ZyA6YeN5ZWfIFRvbWNhdO+8ieOAggoKCgp3ZWIueG1s77ya5piv5ZCm5Yqg5YWl5LqGIDxyZXNvdXJjZS1yZWY+77yfCgoKClhNTAoKCgo8cmVzb3VyY2UtcmVmPgoKICAgIDxyZXMtcmVmLW5hbWU+amRiYy9NeU1zc3FsRFM8L3Jlcy1yZWYtbmFtZT4KCiAgICA8cmVzLXR5cGU+amFrYXJ0YS5zcWwuRGF0YVNvdXJjZTwvcmVzLXR5cGU+IDxyZXMtYXV0aD5Db250YWluZXI8L3Jlcy1hdXRoPgoKPC9yZXNvdXJjZS1yZWY+CgrpjK/oqqToqIrmga/ororljJbvvJrkv67mlLnngrogamFrYXJ0YSDlvozvvIzlpoLmnpzloLHpjK/orormiJAgTmFtZU5vdEZvdW5kRXhjZXB0aW9u77yM5Luj6KGoIFNwcmluZyDmib7lvpfliLDot6/lvpHkvYYgVG9tY2F0IOaykuaPkOS+m++8jOmAmeaZguiri+aqouafpSBzZXJ2ZXIueG1sIOeahCBuYW1lIOaYr+WQpuaLvOmMr+OAggoKCgrkvaDmg7PorpPmiJHluavkvaDmqqLmn6XkvaDnmoQgc2VydmVyLnhtbCDlhaflrrnvvIznnIvnnIsgUmVzb3VyY2Ug5qiZ57Gk5a+r5b6X5bCN5LiN5bCN5ZeO77yfCg==