首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 客戶端與 Servlet 通訊實戰:存取 Access 資料庫完整範例

     編輯:J2ME

架構總覽

經典三層架構在 J2ME 專案中的落地:

[J2ME MIDlet] <-- HTTP + DataInput/OutputStream --> [Servlet (Tomcat)] <-- JDBC-ODBC Bridge --> [Access .mdb]

本文提供從環境建置、MIDlet 端、Servlet 端、資料庫設定到部署驗證的完整步驟。

一、開發環境需求

  • OS: Windows 2000 / XP / 7+
  • JDK 1.4.2+ (Tomcat 5.x 需 1.4+,勿用 1.3)
  • J2ME WTK 2.1+
  • Apache Tomcat 5.0+
  • Microsoft Access (建立 .mdb 並設定 ODBC)

二、資料庫與 ODBC 設定

  1. 建立 test.mdb,資料表 user:欄位 id (自動編號)、name (文字)。
  2. 控制台 → 系統管理工具 → 資料來源 (ODBC) → 系統 DSN → 新增 → Microsoft Access Driver (*.mdb) → 資料源名稱: mydata → 選取 test.mdb (路徑勿含中文)。

三、MIDlet 端實作

NetMain.java — 主入口與啟動畫面

public class NetMain extends MIDlet implements CommandListener {
    private Display display;
    private Form mainForm;
    private Command connectCmd = new Command("連線查詢", Command.OK, 1);

    public NetMain() { display = Display.getDisplay(this); }

    protected void startApp() {
        mainForm = new Form("J2ME 聯網測試");
        mainForm.append("點擊下方按鈕向 Servlet 發送查詢請求");
        mainForm.addCommand(connectCmd);
        mainForm.setCommandListener(this);
        display.setCurrent(mainForm);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == connectCmd) {
            display.setCurrent(new SendMsgForm(this));
        }
    }
    // pauseApp, destroyApp, exit 略...
}

SendMsgForm.java — 聯網執行緒與 HTTP GET 處理


public class SendMsgForm extends Form implements CommandListener, Runnable {
    private static final String SERVLET_URL = "https://localhost:8080/returnMsg";
    private Thread connThread;
    private NetMain parent;
    private Command exitCmd = new Command("返回", Command.BACK, 1);

    public SendMsgForm(NetMain parent) {
        super("查詢結果");
        this.parent = parent;
        append("正在連線伺服器...");
        addCommand(exitCmd);
        setCommandListener(this);
        connThread = new Thread(this);
        connThread.start();
    }

    public void run() {
        try {
            String result = sendHttpGet(SERVLET_URL);
            // 在事件執行緒更新 UI
            Display.getDisplay(parent).callSerially(() -> {
                deleteAll();
                append(result);
            });
        } catch (IOException e) {
            Display.getDisplay(parent).callSerially(() -> {
                deleteAll();
                append("連線失敗: " + e.getMessage());
            });
        }
    }

    private String sendHttpGet(String url) throws IOException {
        HttpConnection conn = null;
        DataInputStream dis = null;
        StringBuffer sb = new StringBuffer();
        try {
            conn = (HttpConnection) Connector.open(url);
            dis = new DataInputStream(conn.openInputStream());
            String line;
            // 注意:Servlet 端使用 writeUTF,需配合 readUTF 讀取
            while ((line = dis.readUTF()) != null) {
                sb.append(line).append("\n");
            }
        } finally {
            if (dis != null) dis.close();
            if (conn != null) conn.close();
        }
        return sb.toString();
    }

    public void commandAction(Command c, Displayable d) {
        if (c == exitCmd) parent.exit();
    }
}

四、Servlet 端實作

returnMsg.java — JDBC 查詢並以 DataOutputStream 回傳


public class returnMsg extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

        res.setContentType("application/octet-stream"); // 二進位串流
        ServletOutputStream out = res.getOutputStream();
        DataOutputStream dos = new DataOutputStream(out);

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            // 載入 JDBC-ODBC Bridge 驅動 (JDK 內建)
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            conn = DriverManager.getConnection("jdbc:odbc:mydata");
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT id, name FROM user");

            dos.writeUTF("=== 查詢結果 ===");
            while (rs.next()) {
                dos.writeUTF("用戶ID: " + rs.getString("id"));
                dos.writeUTF("用戶名: " + rs.getString("name"));
            }
            dos.flush();
        } catch (Exception e) {
            dos.writeUTF("伺服器錯誤: " + e.getMessage());
        } finally {
            try { if (rs != null) rs.close(); } catch (Exception ignore) {}
            try { if (stmt != null) stmt.close(); } catch (Exception ignore) {}
            try { if (conn != null) conn.close(); } catch (Exception ignore) {}
        }
    }
}

web.xml 部署描述檔


<web-app>
  <servlet>
    <servlet-name>returnMsg</servlet-name>
    <servlet-class>returnMsg</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>returnMsg</servlet-name>
    <url-pattern>/returnMsg</url-pattern>
  </servlet-mapping>
</web-app>

編譯與部署步驟

  1. javac -cp ".;%CATALINA_HOME%\common\lib\servlet-api.jar" returnMsg.java
  2. 將 returnMsg.class 放入 %CATALINA_HOME%\webapps\ROOT\WEB-INF\classes\
  3. 編輯 %CATALINA_HOME%\webapps\ROOT\WEB-INF\web.xml 加入上述 servlet 映射。
  4. 啟動 Tomcat:startup.bat
  5. 瀏覽器驗證:https://localhost:8080/returnMsg (查看網頁原始碼應見查詢結果)。

五、WTK 專案建置與測試

  1. WTK 建立新專案,將 NetMain.java、SendMsgForm.java 放入 src 目錄。
  2. Build → Run,模擬器啟動。
  3. 點擊「連線查詢」→ 進入 SendMsgForm → 顯示從 Servlet 回傳的用戶資料。

六、常見問題與解決

現象原因解決
Tomcat 啟動報 "Unsupported JNI version"JDK 版本過低升級 JDK 1.4.2+
Servlet 編譯找不到 javax.servletclasspath 缺 servlet-api.jar加入 %CATALINA_HOME%\common\lib\servlet-api.jar
MIDlet 連線報 SecurityException未簽名 MIDlet 存取網路需用戶授權WTK 專案屬性勾選 "Remove leading zeros" 或簽名發布
Access 查詢亂碼字元編碼不匹配Servlet 端 dos.writeUTF 已處理 Unicode,MIDlet 端 readUTF 正確還原

七、進階擴充建議

  • 改用 POST + JSON:傳遞複雜查詢參數,回傳結構化資料,解耦雙端協定。
  • 連線池:Tomcat 設定 JNDI DataSource 替代 JDBC-ODBC Bridge,支援 MySQL/SQL Server 等生產級資料庫。
  • 異步非阻塞:MIDP 2.0 可使用 Connector.openAsync (若支援) 或自行執行緒池管理。
  • 安全性:加入 HTTPS、Token 驗證、SQL 注入防護 (PreparedStatement)。

小結

本文提供了從零開始建立「J2ME + Servlet + Access」完整聯網應用的最小可行性路徑。掌握此流程後,可輕鬆擴展至企業級行動應用架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved