3G 時代來臨,手機聯網應用爆發。受限於手機算力、內存、帶寬,採用 C/S 架構:J2ME 客戶端負責展現與輕邏輯,J2EE 服務端承擔數據存儲與重邏輯。本文詳細講解基於 MVC 分層的 J2ME 客戶端設計、RMS 持久化、HTTP 通信協議及服務端 Servlet 實現,附完整代碼與運行截圖。
| 層 | 職責 | 關鍵類 |
|---|---|---|
| Handle (Controller) | 流程控制、網絡請求分發、簡單業務邏輯、協調各層 | WbAction |
| DAO | 封裝 RMS 讀寫,提供數據訪問接口 | WbDao |
| Database | 關鍵數據持久化(RMS RecordStore 或文件) | RecordStore |
| Model | 業務數據實體與行為封裝 | UrlEntity |
| View | UI 顯示、鍵盤事件響應、與 Handle 交互 | WebBrowser (MIDlet) |

WebBrowser.startApp() → WbAction.getNews()WbDao 從 RMS 讀取默認 URL (UrlEntity)WbAction 啟動 WebExplorer 線程發起 HTTP GETNewsListServlet 抓取目標站點,解析標題列表,返回 UTF 文本服務端只返回純文本(標題/正文),過濾 HTML 標籤,大幅降低流量與解析開銷。
public class WebBrowser extends MIDlet implements CommandListener {
private Display display; private Form mainForm;
private static final Command EXIT = new Command("Exit", Command.OK, 1);
public void startApp() {
display = Display.getDisplay(this);
mainForm = new Form("News Form");
WbAction action = new WbAction();
String newsList = action.getNews(); // 同步等待網絡
mainForm.append(newsList);
mainForm.addCommand(EXIT);
mainForm.setCommandListener(this);
display.setCurrent(mainForm);
}
public void commandAction(Command c, Displayable d) {
if (c == EXIT) { destroyApp(false); notifyDestroyed(); }
}
// pauseApp/destroyApp 空實現
}
public class WbAction {
public String getNews() {
UrlEntity ue = new WbDao().getDefaultURL();
WebExplorer we = new WebExplorer(ue.getUrl());
we.start();
while (!we.isComplete()) { /* 可加超時邏輯 */ }
return we.getNewsList();
}
class WebExplorer extends Thread {
private String url, newsList;
public void run() {
try {
HttpConnection conn = (HttpConnection) Connector.open(url);
DataInputStream is = conn.openDataInputStream();
newsList = is.readUTF(); // 服務端 writeUTF
} catch (IOException e) { e.printStackTrace(); }
}
public boolean isComplete() { return newsList != null; }
public String getNewsList() { return newsList; }
}
}
public class WbDao {
public UrlEntity getDefaultURL() {
// 實際應從 RMS 讀取,此處硬編碼演示
UrlEntity ue = new UrlEntity();
ue.setName("Test Web URL");
ue.setUrl("https://localhost:8080/rss/news");
return ue;
}
}
public class UrlEntity {
private String name, url;
// getter/setter 省略
}
public class NewsListServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String url = "https://www.techweb.com.cn/news/20.shtml";
Robot robot = RobotFactory.getInstance(Robot.HTML, url); // 核心解析器
List list = robot.parseList();
StringBuilder sb = new StringBuilder();
int i = 0;
for (Object o : list) {
DataModel dm = (DataModel) o;
sb.append(++i).append('.').append(dm.getLinkText()).append('\n');
}
try (DataOutputStream dos = new DataOutputStream(resp.getOutputStream())) {
dos.writeUTF(sb.toString());
}
}
}
