You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

M1芯片环境下Eclipse中Java与MySQL连接后Tomcat运行遇双重错误求助

M1 Eclipse环境下Tomcat 404及ATS连接错误排查方案

我用M1芯片设备在Eclipse里已经成功完成数据库与Tomcat的连接,但目前碰到两个疑似关联的问题,下面针对每个问题给出具体的排查和解决思路:

一、HTTP 404错误(已排查路径、Java版本、文件位置仍未解决)

404本质是请求的资源在Tomcat里找不到,除了你已经检查的点,还可以从这些方向入手:

  • 确认项目部署状态:打开Eclipse的Tomcat Server配置,查看「Server Locations」是否设置正确(建议选「Use Tomcat installation」),然后去Tomcat的webapps目录看看你的项目文件夹是不是已经生成,或者去work/Catalina/localhost下有没有对应项目的编译文件——M1架构下偶尔会出现部署权限问题,导致项目没被正确拷贝到Tomcat目录。
  • 检查请求URL的完整性:比如你的Web项目上下文路径是不是被你忽略了?假设你的项目名为productSystem,要访问Servlet的话,完整URL应该是http://localhost:8080/productSystem/xxx,而不是直接http://localhost:8080/xxx。可以在Eclipse里右键项目→「Properties」→「Web Project Settings」查看上下文路径。
  • 查看Tomcat日志定位细节:去Tomcat安装目录的logs文件夹,打开localhost.loglocalhost_access_log.*.txt,里面会记录每个请求的具体路径和服务器返回码,能帮你判断是路径写错了,还是资源真的不存在。
  • 适配M1架构的版本检查:确保你用的Tomcat是ARM64版本(Tomcat 9.0.40+基本都支持),Eclipse也选ARM版本的,别用x86转译的版本,转译模式下可能会出现部署异常或者路径映射错误。

二、App Transport Security(ATS)安全连接错误

提示信息:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection,改了info.plist仍未解决。

这个错误是苹果的ATS政策限制,要求应用使用HTTPS连接,你的情况大概率是客户端(比如iOS/macOS应用的WebView、或者Mac上的桌面应用)请求了HTTP资源,和数据库JDBC连接无关(JDBC用的是MySQL协议,不会触发ATS)。可以按以下步骤处理:

1. 确认info.plist修改是否正确

如果是iOS/macOS项目,要确保ATS的配置完全正确,比如添加以下配置到info.plist

<key>NSAppTransportSecurity</key>
<dict>
    <!-- 允许所有HTTP请求(开发环境可用,生产环境不建议) -->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

或者更安全的方式,只允许你的Tomcat域名:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
        <!-- 如果你的Tomcat部署在其他域名,也在这里添加 -->
    </dict>
</dict>

还要确认修改的info.plist是对应项目的目标文件,比如在Xcode里要选对Target,Eclipse里要确保文件被包含到打包资源中。

2. 给Tomcat配置HTTPS(推荐生产环境使用)

如果不想修改ATS配置,可以给Tomcat开启HTTPS,让客户端用HTTPS访问:

  1. 生成SSL证书(用Java的keytool命令):
keytool -genkey -alias tomcat -keyalg RSA -keystore ./tomcat.keystore
  1. 修改Tomcat的conf/server.xml,启用8443端口的Connector:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="conf/tomcat.keystore"
                     type="RSA" />
    </SSLHostConfig>
</Connector>

之后用https://localhost:8443/你的项目名访问,就能绕过ATS限制。

附:你的数据库操作代码(可优化点)

package product;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class productMgr {
    public ArrayList<product> getProduct(int categoryID) throws SQLException, ClassNotFoundException {
        ArrayList<product> products = new ArrayList<>();
        // 注意:MySQL 8.0+推荐使用com.mysql.cj.jdbc.Driver,且JDBC4.2+无需手动Class.forName()
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            String sql = "select * from product where categoryId = ?";
            // 替换成实际的数据库地址、库名,建议添加useSSL=false&serverTimezone=UTC参数
            String jdbcDriver = "**jdbc:mysql://address**";
            String dbUser = "**root**";
            String dbPwd = "**pw**";
            conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPwd);
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, categoryID);
            rs = stmt.executeQuery();
            while(rs.next()) {
                String ProductID = rs.getString("productID");
                int CategoryID = rs.getInt("categoryID");
                String ProductName = rs.getString("productName");
                int Price = rs.getInt("price");
                int Amount = rs.getInt("amount");
                products.add(new product(ProductID, CategoryID, ProductName, Price, Amount));
            }
            return products;
        }catch (SQLException se) {
            throw new RuntimeException("A database error occured. " + se.getMessage());
        }catch (Exception e) {
            throw new RuntimeException("Exception: " + e.getMessage());
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException se) {
                    se.printStackTrace(System.err);
                }
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException se) {
                    se.printStackTrace(System.err);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
            }
        }
    }
}

相关截图

错误截图1
错误截图2
错误截图3
错误截图4

内容的提问来源于stack exchange,提问作者호찌누나

火山引擎 最新活动