使用 JSR 172 JAX-RPC 调用远程服务一旦生成、编译并部署了 JSR 172 JAX-RPC 存根和支持文件,消费远程服务就很容易了。事实上,除了导入 RemoteException,完成最少量的 JAX-RPC 细节初始化工作,您的应用程序不光是看上去,而且运行起来也和非 Web 服务消费者应用程序一样。由于有 JSR 172 存根和运行时,实现这种简单的应用程序是可能的,正如前面提到的,JSR 172 存根和运行时把与远程调用相关的大部分细节都隐藏了。
要调用远程服务,您首先需要实例化存根,完成最少的存根初始化工作,然后就是如何编写调用存根方法。下面的代码片断显示了如何使用 JSR 172 JAX-RPC 调用远程服务。
清单 1:调用远程服务
package j2medeveloper.wsasample
// MIDP import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form;
...
Form form = new Form("Employee Info");
...
// JAX-RPC import java.rmi.RemoteException; String serviceURL = "www.j2medeveloper.com/webservicesample";
...
/** * Entry point to MIDlet, from start or restart states. * @throws javax.microedition.midlet.MIDletStateChangeException */ public void startApp() throws MIDletStateChangeException { // Instantiate the service stub. EmployeeService_Stub service = new EmployeeService_Stub(); // Initialize the stub/service. service._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, serviceURL); service._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, new Boolean(true)); ... display.setCurrent(mainScreen); }
/** * Paused state. Release resources (connection, threads, etc). */ public void pauseApp() { ... }
/** * Destroy state. Release resources (connection, threads, etc). * @param uc If true when this method is called, the MIDlet must * cleanup and release all resources. If false the MIDlet may * throw MIDletStateChangeException to indicate it does not want * to be destroyed at this time. * @throws javax.microedition.midlet.MIDletStateChangeException * to indicate it does not want to be destroyed at this time. */ public void destroyApp(boolean uc) throws MIDletStateChangeException { ... }
: :
/** * Command Listener. * @param c is the LCDUI Command. * @param d is the source Displayable. */ public void commandAction(Command c, Displayable d) { if (c == UiConstants.COMMAND_GET_EMPINFO) { Thread th = new Thread(new GetEmpInfoTask()); th.start(); } else { ... } : : }
/** * On its own thread, invoke the remote service getEmployeeInfo */ public class GetEmpInfoTask implements Runnable { public void run() { try { // Invoke the remote service. EmployeeInfo empInfo = service.getEmployeeInfo(empId); : : // Display the employee Information form.append("Name:" + empInfo.firstname+empInfo.lastname); form.append("Status:"+empInfo.status);
: :
display.setCurrent(form); } catch (RemoteException e) { // Handle RMI exception. } catch (Exception e) { // Handle exception. } }
} : :
注意远程调用是如何在自己的执行线程中执行的。由于 JSR 172 中的远程调用是按模块进行的,而且如果在主事件线程中调用,用户界面会冻结,直到远程调用结束。
结束语
本文介绍了用于 J2ME 平台的 JSR 172 WSA,重点介绍了用于 J2ME 远程服务调用 API 的 JAX-RPC。另外,还涵盖了 JSR 172 WSA 中用到的核心 Web 服务标准、典型结构以及调用模型。并用一个简短的代码实例回顾了如何消费 Web 服务,即 JAX-RPC 子集 API。 |